/////
Search
Duplicate

Delete Duplicate Emails

태그
DELETE
링크
한 번 더 체크

문제

Table: Person
+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | email | varchar | +-------------+---------+ id is the primary key column for this table. Each row of this table contains an email. The emails will not contain uppercase letters.
Plain Text
복사
Write an SQL query to delete all the duplicate emails, keeping only one unique email with the smallest id. Note that you are supposed to write a DELETE statement and not a SELECT one.
Return the result table in any order.
The query result format is in the following example.

예시

Input: Person table: +----+------------------+ | id | email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | | 3 | john@example.com | +----+------------------+ Output: +----+------------------+ | id | email | +----+------------------+ | 1 | john@example.com | | 2 | bob@example.com | +----+------------------+ Explanation: john@example.com is repeated two times. We keep the row with the smallest Id = 1.
Plain Text
복사

정답

1. WHERE 절 이용
DELETE FROM person WHERE id NOT IN (SELECT * FROM(SELECT MIN(id) FROM person GROUP BY Email) P1);
SQL
복사
2.
셀프 조인 이용
DELETE p1 FROM Person p1, Person p2 WHERE p1.Email = p2.Email AND p1.Id > p2.Id
SQL
복사

풀이

1.
WHERE 절 이용
우선 이메일 별로 그룹핑을 해서 가장 작은 id만을 뽑아낸 테이블을 만들자.
SELECT MIN(id) FROM person GROUP BY Email
SQL
복사
그럼 이제 id가 이 테이블의 id 안에 포함되어 있다면 중복 가능한 email들 중에서 가장 작은 id임을 알 수 있으므로 WHERE절의 조건으로 사용하자. 그런데 다음과 같이 바로 사용하면 에러가 발생한다.
WHERE id NOT IN (SELECT MIN(id) FROM person GROUP BY Email);
SQL
복사
왜냐하면 UPDATE나 DELETE를 수행할 때 WHERE 절에 동일한 테이블을 참조할 수 없기 때문이다. (현재 참조하고 있는 테이블이 변동하면 안 되기 때문)
따라서 다음과 같이 서브쿼리로 한 번 더 묶어주어야 한다.
WHERE id NOT IN (SELECT * FROM(SELECT MIN(id) FROM person GROUP BY Email) P1);
SQL
복사
→ 즉, 가장 작은 id의 정보만 담고 있는 테이블을 만들고 이를 *를 사용해서 전부 참조하는 방식.