删除重复的电子邮件

编写一个 SQL 查询,来删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。

1
2
3
4
5
6
7
8
+----+------------------+
| Id | Email |
+----+------------------+
| 1 | john@example.com |
| 2 | bob@example.com |
| 3 | john@example.com |
+----+------------------+
Id 是这个表的主键。

例如,在运行你的查询语句之后,上面的 Person 表应返回以下几行:

1
2
3
4
5
6
+----+------------------+
| Id | Email |
+----+------------------+
| 1 | john@example.com |
| 2 | bob@example.com |
+----+------------------+

解题思路

  1. 找到邮箱重复且id不是最小的记录
  2. 进行查询排除或者删除原表记录

代码

查询

1
2
3
4
5
6
7
SELECT 
id,email
FROM person
WHERE id NOT IN(
SELECT p1.`Id`
FROM person p1,person p2
WHERE p1.`Id`>p2.`Id` AND p1.`Email`=p2.`Email`)

原表中删除记录

错误代码:

DELETE FROM person
WHERE id IN(
SELECT p1.Id
FROM person p1,person p2
WHERE
p1.Id>p2.Id
AND
p1.Email=p2.Email)

错误提示:

You can't specify target table 'person' for update in FROM clause

翻译:你不能在FROM子句中引用person表(也就是原表)

正确代码:

1
2
DELETE p1 FROM person p1,person p2
WHERE p1.`Id`>p2.`Id` AND p1.`Email`=p2.`Email`