2011-10-27 50 views
2

我需要从表内找到并删除重复项,但记录要删除的记录的ID并将其添加到'deleted_ids'字段。SQL删除重复项 - 保留已删除的ID

例如,这里有一个表的一部分,我现在:

+--------+-------------------------------------------------------+ 
| Id  | Name             | 
+--------+-------------------------------------------------------+ 
| 9627 | John Smith           | 
| 9657 | John Smith           | 
| 24455 | John Smith           | 
| 67435 | John Smith           | 
+--------+-------------------------------------------------------+ 

我想达到的效果是:

+--------+-----------------------------+-------------------------+ 
| Id  | Name      | Deleted_Ids    | 
+--------+-----------------------------+-------------------------+ 
| 9627 | John Smith     | 9657,24455,67435  | 
+--------+-----------------------------+-------------------------+ 

我欢迎任何可行的方法,如果任何人都可以提供解决方案或给我建议,我真的很感激它。

感谢, 保罗

+0

你需要什么样的删除项目列表?你有没有考虑过使用“逻辑删除”而不是“物理删除”? –

回答

2

如果你想继续这样,这是一个简单的方法。
一口气做完一笔交易可以肯定。
如果在tbl_del中可能有'John Smith'的条目,则必须检查并且UPDATE来代替添加已删除的ID。

BEGIN; 

INSERT INTO tbl_del 
SELECT name, GROUP_CONCAT(id) AS deleted 
FROM tbl_live 
WHERE name = 'John Smith' 
GROUP BY 1; 

DELETE FROM tbl_live 
WHERE name = 'John Smith'; 

COMMIT; 

但我认为Veseliq有一个vaid点。

4

不要与另一列做到这一点 - 存储ID作为逗号分开,感觉不对,不是吗?

最好是有第二个表有两列PrimaryUserId和DeletedUserId - 例如PrimaryUserId将是“9627” - 您实际保留的记录之一,并且您将为您从您的删除的每个副本添加一行主表。这种方法也可以让你存储一个列,知道重复条目何时被删除。

+0

我想过,如果一个明智的解决方案弹出,我会考虑它。唯一的问题是我正在处理200毫米的行 - 而且deleted_ids很少被访问。所以逗号分隔的方法将是理想的存储原因。 –

+0

@保罗:这是最好的。您可以修改Erwin的这个方法的事务。 –

+0

存储的差异很小。 –

1

的基本方法可首先选择从旧表中的所有行,有资格的缺失标准 - > 插入这些行插入到新表 - > 从旧表

INSERT INTO new_table 
SELECT id,name FROM old_table WHERE id > 
(
    SELECT min(id) FROM old_table B 
    WHERE A.name = B.name 
); 

delete FROM old_table WHERE id > 
(
    SELECT min(id) FROM old_table B 
    WHERE A.name = B.name 
); 

可以删除所有行在新表中有自动递增键。 我还没有运行这些查询,请原谅,如果这里有一些错误,那只是一个想法。 在这两个表格内具有一对多的关系可以在将来真正得心应手....而且更容易查询数据

+0

没有注意到答案已被接受 – Zohaib