HAZEL

[SQL : DELETE / 서브쿼리 / INNER JOIN] LeetCode : 196. Delete Duplicate Emails 본문

DATA ANALYSIS/SQL

[SQL : DELETE / 서브쿼리 / INNER JOIN] LeetCode : 196. Delete Duplicate Emails

Rmsid01 2021. 3. 9. 18:27

196. Delete Duplicate Emails


>> 문제

Write a SQL query to delete all duplicate email entries in a table named Person, keeping only unique emails based on its smallest Id.

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
| 3  | john@example.com |
+----+------------------+
Id is the primary key column for this table.

For example, after running your query, the above Person table should have the following rows:

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
+----+------------------+

Note:

Your output is the whole Person table after executing your sql. Use delete statement.

 

>> 해결 코드 1 : 서브쿼리를 사용한 방법 

DELETE FROM Person
WHERE ID NOT IN
    (SELECT 
      id FROM 
            ( 
                SELECT email,
                        min(id) as id
                FROM Person
                Group by 1) temp
        )

** 이 리트 코드에서 select 로 확인하는 것을 막아두어.. 코드짜는 것이 너무나도 번잡스러웠다.ㅠ..ㅠ..

 

 

** 문제를 푸는 생각 ! 

 

1. 이메일을 GROUP BY 하여, email, min(id) 를 select 하면, id가 작고, email의 그룹바이 값이 나옴 

    -> 이건 삭제 하는 것이 아니라, 출력(보여지는 것 ) 이 위의 값이 나오는 것이다. 

SELECT email , min(id)
FROM person
GROUP BY email

 

2. 그것을 FROM 서브쿼리를 이용해서 감싸준다. 

   -> 아래 값의 출려 결과는 , min_id = 1,2 가 된다. 

SELECT sub.min_id
FROM (
    SELECT email , min(id) as min_id 
    FROM person
    GROUP BY email
    ) sub

 

3.  이제 진짜 목적인, person 이라는 테이블에서 이메일이 중복되면서, 아이디카 큰 값을 삭제해주는 코드로 해준다.

   -> 여기서 not in 을 해준 것은 위의 min_id 값이 1,2 가 나오는 것처럼, 작은 값들이 나오기 때문이다. 

DELETE FROM Person
WHERE ID NOT IN
    (SELECT 
      id FROM 
            ( 
                SELECT email,
                        min(id) as id
                FROM Person
                Group by email) temp
        )

 

※ 여기서, max로 바꿔주고, IN 을 써주지 않는 이유는, GROUP BY email 의 조건이 사라지기 때문이다. 

    즉, 이메일이 같은 애들을 제거해줘야하는데, max 와 in 을 사용하면,, 의미가 없어지게 된다. 

 

 

>> 해결 코드 2 : INNER JOIN ( SELF JOIN ) 을 이용한 방법 

DELETE  P1 
FROM Person P1
    INNER JOIN Person P2 ON P1.email = P2.email and p1.id != p2.id
    -- INNER JOIN Person P2 ON P1.email = P2.email 
    WHERE p1.id > p2.id

 

가장 먼저 생각했던 방법인 INNER JOIN 이다. 

하지만, DELETE 에 테이블명을 적고 FROM 이후에 또 테이블을 적는것을 몰라서 조금 고생했다. 

 

코드에서 눈에 띄는 것은 DELETE 옆에 테이블 명 을 써주고, FORM 이후에도 테이블 명을 적어주는 것이다.

 

DELETE에서 JOIN을 사용하는 경우, 

 

DELETE 테이블명 1 , 테이블명 2

FROM 테이블명1 

    INNER JOIN 테이블명 2 ON ~ 

 

의 모습으로 코드를 적어준다. 이렇게, DELETE 옆에 쓰는 이유는 조인 이후에도 삭제테이블을 지정해주기 위해 테이블명을 지정하는 것이다. 즉, 제거해주고 싶은 테이블명을 적어주는 것이다.

 

 

※ 참고 블로그

https://www.mysqltutorial.org/mysql-delete-join/

 

MySQL DELETE JOIN: Deleting Data from Multiple Tables

This tutorial shows you how to delete data from multiple tables by using MySQL DELETE JOIN statement with INNER JOIN and LEFT JOIN.

www.mysqltutorial.org

leetcode.com/problems/delete-duplicate-emails/submissions/

 

Delete Duplicate Emails - LeetCode

Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.

leetcode.com