如何在数据库中查找重复项?

时间:2012-07-12 22:26:31

标签: php mysql duplicates duplicate-removal

关于如何在数据库中查找重复项有很多问题,但不是我遇到的具体问题。

我有一张大约一张桌子。 120000个条目。我需要找到重复项。为了找到它们,我使用了一个结构如下的PHP脚本:

//get all entries from database
//loop through them
    //get entries with greater id
    //compare all of them with the original one
    //update database (delete duplicate, update information in linked tables, etc.)

无法整理初始查询中已有的所有重复项,因为我必须遍历所有条目,因为我的重复搜索不仅对100%相似的条目敏感,而且对90%相似的条目也很敏感。我为此使用了similar_text()。

我认为第一个循环是可以的,但循环遍历循环中的所有其他条目太多了。有120000个条目,这将接近(120000 ^ 2)/ 2次迭代。

因此,不必在循环中使用循环,必须有更好的方法来实现它。你有什么想法?我想过使用in_array(),但它对90%的字符串相似性不敏感,而且也没有给我发现重复的数组字段 - 我需要那些来获取条目'id来更新数据库正确。

有什么想法吗?

非常感谢!

查尔斯

更新1

我现在使用的查询如下:

SELECT a.host_id
FROM host_webs a
JOIN host_webs b ON a.host_id != b.host_id AND a.web = b.web
GROUP BY a.host_id

它完美地显示原件和副本,但我需要摆脱原件,即与相关数据一起找到的第一个原件。我怎么能做到这一点?

2 个答案:

答案 0 :(得分:2)

你可以JOIN将表格放到自己身上并在SQL中完成所有操作(我知道你说你不认为可以,但如果是这样的话,我会感到惊讶)。您需要做的就是将用于测试重复项的所有列放入ON的{​​{1}}子句中。

JOIN

这将只返回SELECT id FROM tablename a JOIN tablename b ON a.id != b.id AND a.col1 = b.col1 AND a.col2 = b.col2 GROUP BY id id重复的行的col1个。您可以将所需的任何字符串比较合并到此中,col2子句可以像您需要的那样复杂。例如:

ON

修改

由于您实际执行查询的所有操作都在查找SELECT id FROM tablename a JOIN tablename b ON a.id != b.id AND (a.col1 = b.col1 AND (a.col2 = b.col2 OR a.col3 = b.col3)) OR ((a.col1 = b.col1 OR a.col2 = b.col2) AND a.col3 = b.col3) OR (SOUNDEX(a.col1) = SOUNDEX(b.col1) AND SOUNDEX(a.col2) = SOUNDEX(b.col2) AND SOUNDEX(a.col3) = SOUNDEX(b.col3)) GROUP BY id 列相同的行,因此只能查找重复项而不是原始的“好”记录 - 假设{{1 }是数字,“好”记录将是web

最低的记录
host_id

我想这里的结局游戏将删除重复项,所以如果你感觉很勇敢,你可以一次删除它们:

host_id

SELECT b.host_id FROM host_webs a INNER JOIN host_webs b ON b.web = a.web AND b.host_id > a.host_id GROUP BY b.host_id 语句中不需要DELETE b.* FROM host_webs a INNER JOIN host_webs b ON b.web = a.web AND b.host_id > a.host_id ,因为如果您尝试在单个语句中多次删除同一行并不重要。

答案 1 :(得分:0)

如果你一次性删除重复的项目,我就不会去编写一个php脚本了 - 在sql中这样做更干净。

我发现删除重复项的一般算法效果最好:
 1.复制表
 2.截断原始表
 3.在需要唯一的列上设置唯一索引  4.使用INSERT IGNORE INTO original_table SELECT * FROM duplicate_tableREPLACE INTO original_table SELECT * FROM duplicate table
重新插入行  5.修复链接表 - 删除孤立行(DELETE x FROM x LEFT JOIN original TABLE ON (...) WHERE original_table.id IS NULL