如何从MySQL表中删除所有重复数据?

以以下数据为例:

SELECT * FROM names;

+----+--------+
| id | name   |
+----+--------+
| 1  | google |
| 2  | yahoo  |
| 3  | msn    |
| 4  | google |
| 5  | google |
| 6  | yahoo  |
+----+--------+

我将使用SELECT DISTINCT name FROM names;如果它是一个SELECT查询。

如何使用DELETE仅删除重复项并只保留每个记录?


当前回答

编辑器警告:此解决方案计算效率低,可能会导致大型表的连接中断。

注意:您需要首先在表的测试副本上执行此操作!

当我这样做的时候,我发现除非我还包括n1。Id <> n2。Id,它删除了表中的每一行。

如果你想保留id值最低的行: DELETE n1 FROM names n1, names n2 WHERE n1。Id > n2。id AND n1.name = n2.name 如果你想保留id值最高的行: DELETE n1 FROM names n1, names n2 WHERE n1。Id < n2。id AND n1.name = n2.name

我在MySQL 5.1中使用了这种方法

不确定其他版本。


更新:因为人们在谷歌上搜索删除重复项的结果是在这里 虽然OP的问题是关于DELETE的,但请注意使用INSERT和DISTINCT会更快。对于一个有800万行的数据库,下面的查询花了13分钟,而使用DELETE,它花了2个多小时,但仍然没有完成。

INSERT INTO tempTableName(cellId,attributeId,entityRowId,value)
    SELECT DISTINCT cellId,attributeId,entityRowId,value
    FROM tableName;

其他回答

编辑器警告:此解决方案计算效率低,可能会导致大型表的连接中断。

注意:您需要首先在表的测试副本上执行此操作!

当我这样做的时候,我发现除非我还包括n1。Id <> n2。Id,它删除了表中的每一行。

如果你想保留id值最低的行: DELETE n1 FROM names n1, names n2 WHERE n1。Id > n2。id AND n1.name = n2.name 如果你想保留id值最高的行: DELETE n1 FROM names n1, names n2 WHERE n1。Id < n2。id AND n1.name = n2.name

我在MySQL 5.1中使用了这种方法

不确定其他版本。


更新:因为人们在谷歌上搜索删除重复项的结果是在这里 虽然OP的问题是关于DELETE的,但请注意使用INSERT和DISTINCT会更快。对于一个有800万行的数据库,下面的查询花了13分钟,而使用DELETE,它花了2个多小时,但仍然没有完成。

INSERT INTO tempTableName(cellId,attributeId,entityRowId,value)
    SELECT DISTINCT cellId,attributeId,entityRowId,value
    FROM tableName;

如果你想保留id值最低的行:

DELETE FROM NAMES
 WHERE id NOT IN (SELECT * 
                    FROM (SELECT MIN(n.id)
                            FROM NAMES n
                        GROUP BY n.name) x)

如果你想要最大的id值:

DELETE FROM NAMES
 WHERE id NOT IN (SELECT * 
                    FROM (SELECT MAX(n.id)
                            FROM NAMES n
                        GROUP BY n.name) x)

子查询中的子查询对于MySQL是必要的,否则您将得到一个1093错误。