【问题标题】:Delete duplicated records from a table without pk or id or unique columns in mysql从没有 pk 或 id 或 mysql 中唯一列的表中删除重复记录
【发布时间】:2014-10-12 02:14:36
【问题描述】:

我需要从我的一个表中删除所有重复的记录,问题是没有任何 id 或唯一或键列,所以我不能做这样的事情:

delete from tbl using tbl,tbl t2 where tbl.locationID=t2.locationID
  and tbl.linkID=t2.linkID  and tbl.ID>t2.ID

因为它需要一个 id 列或唯一或键列 我不能做一个

ALTER IGNORE TABLE 'mytable' ADD UNIQUE INDEX 

因为有些信息总是需要复制,而其他信息则不需要 我做不到:

DELETE FROM 'table' WHERE 'field' IN (SELECT 'field' FROM 'table' GROUP BY 'field'HAVING (COUNT('field')>1))

因为它会删除所有重复的并且永远不会留下一个 这是我的表的一个例子


+----------+----------------------+-------------+-------------+
| phone    | address              | name        | cellphone   |
+----------+----------------------+-------------+-------------+
| 2555555  | 1020 PANORAMA        | JUAN CARLOS | 0999999999  | diferent address
| 2555555  | GABRIEL JOSE 1020    | JUAN CARLOS | 0999999999  | good one
| 2555555  | GABRIEL JOSE 1020    | JUAN CARLOS | 0999999999  | duplicated
| 2555555  | C ATARAZANA 1020     | SILVIA      | 0777777777  | another good one
| 2555555  | C ATARAZANA 1020     | SILVIA      | 0777777777  | another duplicated
| 2555555  | GABRIEL JOSE 1020    | VIOLETA     | 0888888888  | diferent person
+----------+----------------------+-------------+-------------+

这就是我要离开的地方


+----------+----------------------+--------------+-------------+
| phone    | address              | name         | cellphone   |
+----------+----------------------+--------------+-------------+
| 2555555  | 1020 PANORAMA        | JUAN CARLOS  | 0999999999  |
| 2555555  | GABRIEL JOSE 1020    | JUAN CARLOS  | 0999999999  |
| 2555555  | C ATARAZANA 1020     | SILVIA       | 0777777777  |
| 2555555  | GABRIEL JOSE 1020    | VIOLETA      | 0888888888  |
+----------+----------------------+--------------+-------------+

我不能截断或删除原始表,因为它使用 24/7 并且有 10000000 条记录....

请帮帮我。

【问题讨论】:

标签: mysql sql-delete records


【解决方案1】:

使用 ALTER IGNORE 添加唯一索引(包含表的所有列)将消除重复项:

ALTER IGNORE TABLE table_name
  ADD UNIQUE INDEX all_columns_uq
    (phone, address, name, cellphone) ;

SQL-Fiddle 中测试。

注意:在 5.5 版本中(由于实现快速索引创建的一个错误),只有在 ALTER 之前提供此设置时,上述设置才有效:

SET SESSION old_alter_table=1 ;

【讨论】:

  • 不能这样做....总会存在一些具有重复信息的列,例如在同一个电话号码(房子)中将是 3 人....所以我不能做到独一无二电话号码,地址不能是唯一的,因为如果它是一座建筑物,那里可以住许多拥有不同电话的家庭......所以它们不能使用...... :(
  • 我也是+1。我尝试了你的解决方案,但似乎没有得到它的工作。虽然我喜欢这种方法ATTEMPT
  • @JohnRuddell 它适用于 5.1 版,但不适用于 SQLFiddle 的 5.5 版。可能与某些 MySQL 设置有关。 IGNORE 在 5.6 中被弃用并从 5.7 中删除
  • 不,如果您删除IGNORE,重复项肯定会产生错误。使用 IGNORE 查看我的答案中链接的 sqlfiddle,它在哪里工作。
  • 是的,我从未使用过忽略,但我假设这就是它所做的。我喜欢这种方法,因为它非常简单。而且它不添加主键只是一个索引 imo 这应该是公认的答案!
【解决方案2】:

它非常简单,只需创建一个临时表并删除另一个表然后重新创建它

CREATE TEMPORARY TABLE IF NOT EXISTS no_dupes AS 
(SELECT * FROM test GROUP BY phone, address, name, cellphone);

TRUNCATE table test;
INSERT INTO test (phone, address, name, cellphone) 
SELECT phone, address, name, cell FROM no_dupes;

WORKING DEMO

【讨论】:

  • 如果它使用选择不同但我不能删除原始表可以工作....这是一个不错的选择,但在我的情况下.... :(
  • @ss4sgoku 检查我的编辑...尝试 truncate 它将完全清空表格但不会删除它
  • @ss4sgoku 你也不需要区分,因为 group by 句柄
  • 是的,它是一个很好的方法,但我不能截断或删除原始的....它有 10000000 行,所以需要花费一些时间和处理能力来重新制作等...这就是为什么我仍在寻找方法....
  • @ss4sgoku 不管你怎么做,如果桌子很大,这将需要一些时间。顺便说一句,1000 万行并不是那么大。
【解决方案3】:

我会使用子查询。比如:

DELETE FROM table1
WHERE EXISTS (
SELECT field1 
FROM table1 AS subTable1 
WHERE table1.field1 = subTable1.field1 and table1.field2 = subTable1.field2)

虽然没试过。

【讨论】:

  • 啊,我的错。。如果我们将子查询的结果放入某个临时表中(在我们使用 distinct 之后),删除所有重复的记录,然后将临时表中的记录添加到原来的..虽然这似乎不是直截了当,但我能想到的唯一方法。希望看到另一个答案:)
  • 这是一个很好的解决方案....
【解决方案4】:

每个表总是有一个 PK,但您可以将列组合为唯一 ID,因此如果您愿意,可以使用整行作为唯一 ID...但我不建议使用整行,您应该搜索可以使用PK的最重要的列,当你这样做时,你可以复制数据,如果没有问题mysql不会复制重复的行。

对不起我的英语不好

【讨论】:

  • 必须总是有一个 pk....但是这个没有,我无法更改它...所以我没有正常的方法来删除重复的行...这就是我拥有的方式头疼....我可以找到所有重复的记录,有些记录重复了 900 次,有些重复了 400 次,其他的只重复了 3 或 2 次,但我只需要留下一个
猜你喜欢
  • 2013-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 2018-04-02
  • 2010-11-02
相关资源
最近更新 更多