删除除MySQL中的One之外的所有重复行?

Hig*_*ife 403 mysql sql duplicates

可能重复:
删除MySQL中的重复行

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

例如,使用以下数据:

SELECT * FROM names;

+----+--------+
| id | name   |
+----+--------+
| 1  | google |
| 2  | yahoo  |
| 3  | msn    |
| 4  | google |
| 5  | google |
| 6  | yahoo  |
+----+--------+
Run Code Online (Sandbox Code Playgroud)

我会使用,SELECT DISTINCT name FROM names;如果它是一个SELECT查询.

我怎么做DELETE才能删除重复项并保留每个重复记录?

小智 913

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

注意 - 您需要先在桌子的测试副本上执行此操作!

当我这样做时,我发现除非我也包括在内AND n1.id <> n2.id,否则它会删除表格中的每一行.

  1. 如果要保持行具有最低id值:

    DELETE n1 FROM names n1, names n2 WHERE n1.id > n2.id AND n1.name = n2.name
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果要保留具有最高id值的行:

    DELETE n1 FROM names n1, names n2 WHERE n1.id < n2.id AND n1.name = n2.name
    
    Run Code Online (Sandbox Code Playgroud)

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

不确定其他版本.


更新:由于人们谷歌搜索删除重复项最终在这里
尽管OP的问题是关于DELETE,请注意使用INSERTDISTINCT更快.对于具有800万行的数据库,以下查询花费了13分钟,而在使用时DELETE,花费了超过2小时但尚未完成.

INSERT INTO tempTableName(cellId,attributeId,entityRowId,value)
    SELECT DISTINCT cellId,attributeId,entityRowId,value
    FROM tableName;
Run Code Online (Sandbox Code Playgroud)

  • 优秀的解决方 它工作得很好.但我有一个建议,我们应该交换条件.而不是[WHERE n1.id> n2.id AND n1.name = n2.name]我们应该写[WHERE n1.name = n2.name AND n1.id> n2.id]如果我们有这么多,它将提高性能数据. (79认同)
  • 仅供参考:这会忽略列"name"为空的行. (11认同)
  • 我喜欢这个解决方案,但你有建议在更大的桌子上进行优化吗? (6认同)
  • 这个答案中的NB是非常重要的孩子.但这是一个优秀的MySQL.请注意,对于可能重复多次重复的表,您还需要一个`GROUP BY` n1.id子句. (4认同)
  • 这在10,000个记录表上花了171秒,重复450个.OMG小马的回答耗时4秒. (4认同)
  • http://sqlfiddle.com/#!2/e5df9获取架构示例.可能需要加载你的MySQL实例.然后执行:SELECT*FROM deldup; 删除n1 FROM deldup n1,deldup n2 WHERE n1.or_id <n2.or_id AND n1.order_id = n2.order_id AND n1.txt_value = n2.txt_value AND n1.date_of_revision = n2.date_of_revision AND n1.status = n2.status; SELECT*FROM deldup; (3认同)
  • 老兄,有一个"nb"就像你应该把它放在其他一切之前! (2认同)

OMG*_*ies 187

如果要保持行具有最低id值:

DELETE FROM NAMES
 WHERE id NOT IN (SELECT * 
                    FROM (SELECT MIN(n.id)
                            FROM NAMES n
                        GROUP BY n.name) x)
Run Code Online (Sandbox Code Playgroud)

如果您想要id最高的值:

DELETE FROM NAMES
 WHERE id NOT IN (SELECT * 
                    FROM (SELECT MAX(n.id)
                            FROM NAMES n
                        GROUP BY n.name) x)
Run Code Online (Sandbox Code Playgroud)

子查询中的子查询对于MySQL是必需的,否则您将收到1093错误.

  • 但x是什么?(开玩笑) (38认同)
  • 看来这个sql也删除了独特的行.所有行 (10认同)
  • 'x'做什么? (6认同)
  • @GDmac它充当内部查询的别名.如果未指定,则将引发错误. (6认同)
  • @wbinky它充当内部查询的别名.如果未指定,则将引发错误. (5认同)
  • 这是一个更好的解决方案.masa-255的那个不起作用.什么是x? (3认同)
  • 如果您有大数据,这是比masa-255更好的解决方案。谢谢。 (3认同)
  • `x`可以写成`AS x`或`AS temp`或`AS \`temp \``以使其更清楚,它是由外部select生成的表的随机别名.MySQL不允许您对动作(DELETE,UPDATE)和条件使用相同的表,因此将条件包装在另一个SELECT中允许创建临时表并给出别名. (3认同)
  • 一张有500K条记录的表只用了8秒。谢谢。 (3认同)
  • 与接受的答案相比,这是超级快! (3认同)