如何从MySQL数据库中删除重复的条目?

我有一张桌子,上面有一些ids +标题。 我想使标题栏独一无二,但是它已经有超过60万条logging,其中一些是重复的(有时候是几十倍)。

我如何删除所有重复项,除了一个,所以我可以添加一个UNIQUE键后标题列?

此命令添加一个唯一键,并删除所有生成错误的行(由于唯一键)。 这删除重复。

ALTER IGNORE TABLE table ADD UNIQUE KEY idx1(title); 

编辑:请注意,这个命令可能不适用于某些版本的MySQL的InnoDB表 。 看到这个职位的解决方法。 (感谢这个信息的“匿名用户”。)

创build一个只有原始表的不同行的新表。 可能还有其他方法,但我觉得这是最干净的。

 CREATE TABLE tmp_table AS SELECT DISTINCT [....] FROM main_table 

更具体地说 :
更快的方法是将不同的行插入临时表中。 使用删除,我花了几个小时从800万行的表中删除重复。 使用插入和独特,只需要13分钟。

 CREATE TABLE tempTableName LIKE tableName; CREATE INDEX ix_all_id ON tableName(cellId,attributeId,entityRowId,value); INSERT INTO tempTableName(cellId,attributeId,entityRowId,value) SELECT DISTINCT cellId,attributeId,entityRowId,value FROM tableName; DROP TABLE tableName; INSERT tableName SELECT * FROM tempTableName; DROP TABLE tempTableName; 

这显示了如何在SQL2000中执行它。 我不完全熟悉MySQL的语法,但我相信有一些可比的东西

 create table #titles (iid int identity (1, 1), title varchar(200)) -- Repeat this step many times to create duplicates insert into #titles(title) values ('bob') insert into #titles(title) values ('bob1') insert into #titles(title) values ('bob2') insert into #titles(title) values ('bob3') insert into #titles(title) values ('bob4') DELETE T FROM #titles T left join ( select title, min(iid) as minid from #titles group by title ) D on T.title = D.title and T.iid = D.minid WHERE D.minid is null Select * FROM #titles 
 delete from student where id in ( SELECT distinct(s1.`student_id`) from student as s1 inner join student as s2 where s1.`sex` = s2.`sex` and s1.`student_id` > s2.`student_id` and s1.`sex` = 'M' ORDER BY `s1`.`student_id` ASC ) 

Nitin发布的解决scheme似乎是最优雅/合乎逻辑的解决scheme之一。

但是它有一个问题:

错误1093(HY000):您无法在FROM子句中指定目标表'student'进行更新

这可以通过使用(SELECT * FROM student)而不是student来解决:

 DELETE FROM student WHERE id IN ( SELECT distinct(s1.`student_id`) FROM (SELECT * FROM student) AS s1 INNER JOIN (SELECT * FROM student) AS s2 WHERE s1.`sex` = s2.`sex` AND s1.`student_id` > s2.`student_id` AND s1.`sex` = 'M' ORDER BY `s1`.`student_id` ASC ) 

把你的+1joinNitin来提出原来的解决scheme。

由于MySql ALTER IGNORE TABLE 已被弃用 ,所以您需要在添加索引之前实际删除重复的date。

首先写一个查询find所有的重复。 在这里,我假设email是包含重复的字段。

 SELECT s1.email s1.id, s1.created s2.id, s2.created FROM student AS s1 INNER JOIN student AS s2 WHERE /* Emails are the same */ s1.email = s2.email AND /* DON'T select both accounts, only select the one created later. The serial id could also be used here */ s2.created > s1.created ; 

接下来select唯一的重复ID:

 SELECT DISTINCT s2.id FROM student AS s1 INNER JOIN student AS s2 WHERE s1.email = s2.email AND s2.created > s1.created ; 

一旦确定只包含要删除的重复ID,请运行删除。 您必须添加(SELECT * FROM tblname)以便MySql不会抱怨。

 DELETE FROM student WHERE id IN ( SELECT DISTINCT s2.id FROM (SELECT * FROM student) AS s1 INNER JOIN (SELECT * FROM student) AS s2 WHERE s1.email = s2.email AND s2.created > s1.created ); 

然后创build唯一索引:

 ALTER TABLE student ADD UNIQUE INDEX idx_student_unique_email(email) ; 

下面的查询可以用来删除除最低“id”字段值的一行外的所有副本

 DELETE t1 FROM table_name t1, table_name t2 WHERE t1.id > t2.id AND t1.name = t2.name 

以类似的方式,我们可以在'id'中保留具有最高值的行如下

  DELETE t1 FROM table_name t1, table_name t2 WHERE t1.id < t2.id AND t1.name = t2.name 

删除MySQL表上的重复是一个常见问题,通常伴随着特定的需求。 如果有人感兴趣,这里( 在MySQL中删除重复的行 )我解释了如何使用临时表以可靠和快速的方式删除MySQL重复(用不同用例的例子)。

在这种情况下,这样的事情应该工作:

 -- create a new temporary table CREATE TABLE tmp_table1 LIKE table1; -- add a unique constraint ALTER TABLE tmp_table1 ADD UNIQUE(id, title); -- scan over the table to insert entries INSERT IGNORE INTO tmp_table1 SELECT * FROM table1 ORDER BY sid; -- rename tables RENAME TABLE table1 TO backup_table1, tmp_table1 TO table1;