2010-09-08 42 views
13

我有一张数据表,并且有许多来自用户提交的重复条目。删除重复的行离开最旧的行只有?

我想删除基于现场subscriberEmail所有重复的行,只留下最初提交。

换句话说,我想搜索所有重复的邮件,并删除这些行,只留下原来的。

如何在不交换表的情况下做到这一点?
我的表格包含每行的唯一ID。

+0

你应该将答案标记为“已接受”:-) – watery 2015-09-24 11:17:58

回答

27

由于您使用id列作为指标,其中记录是“原始”:

delete x 
from myTable x 
join myTable z on x.subscriberEmail = z.subscriberEmail 
where x.id > z.id 

这将使每个电子邮件地址记录。

编辑补充:

为了解释上面的查询......

这里的想法是加入了对表本身。假装你有两个表格副本,每个副本名称不同。然后,您可以将它们相互比较,并找到最低的ID或每个电子邮件地址。然后,您会看到稍后创建的重复记录,并可能会将其删除。 (我在想这个时候可视化的Excel。)

为了做一个表操作,比较它本身能够识别每一面,你用表的别名。 x是一个表别名。它被分配在from子句中,如下所示:from <table> <alias>。现在可以在同一查询中的其他地方使用x来将该表引用为该快捷方式。

delete x用我们的行动和目标开始查询了。我们将执行查询以从多个表中选择记录,并且我们要删除出现在x中的记录。

别名用于指表中的两个“实例”。 from myTable x join myTable z on x.subscriberEmail = z.subscriberEmail将表格与电子邮件匹配的地方相撞。如果没有后面的where子句,每个记录都会被选中,因为它可能会与自身相结合。

where子句限制了被选择的记录。 where x.id > z.id允许'实例'别名x只包含匹配电子邮件但具有较高值的​​记录。您真正想要的表格中的数据,唯一的电子邮件地址(具有最低的ID)将不会成为x的一部分,并且不会被删除。 x中的唯一记录将是重复记录(电子邮件地址),该记录比该电子邮件地址的原始记录具有更高的id

的加入,where子句可以在这种情况下,进行组合:

delete x 
    from myTable x 
    join myTable z 
    on x.subscriberEmail = z.subscriberEmail 
     and x.id > z.id 

为了防止重复,考虑使SUBSCRIBEREMAIL列的唯一索引的列。

+0

嘿,我不明白X是什么,以及日期输入的地方。我可以使用ID,因为每个ID或日期都有主要ID。 ID听起来更容易 – 2010-09-09 23:20:47

+0

嘿,它的工作!我将“createdOn”更改为“id”,然后马上!哈哈感谢 - 下面有我在PHP使用的代码: 的mysql_query( “删除X 从MY_TABLE X 上x.subscriberEmail加入MY_TABLE Z = z.subscriberEmail 其中x.id> z.id”)或死亡(mysql_error( )); – 2010-09-09 23:42:10

+0

你能解释一下如何用英语阅读这段代码吗 - 它有助于能够逻辑地阅读某些东西来理解语法 - 此外,现在如何防止重复出现?我已经在使用插入IGNORE,但它不会忽略 – 2010-09-09 23:43:14

0

如果每行都有一个唯一的ID,那么可以尝试这样的事情。不要问我为什么你需要第二个select语句,否则mysql不会让我执行。此外,按任何列分组,使您的结果具有独特性。

delete from my_table where id in (
    select id from (
    select id from my_table a group by subscriberEmail having count(*) > 1 
) b 
); 
+1

我相信这会删除所有这些,而不仅仅是临时演员。 – Fosco 2010-09-08 21:17:05

+0

不,它不会。 group by将按像subscriberEmail的行组合。因此,将选择具有多于一封电子邮件的用户(具有计数(*)> 1)。在这一点上,你几乎拥有一组不同的记录用户,并且有超过1封电子邮件。从这个记录集中取出ID并删除它。我尝试过它,它的功能就像一个魅力。 – 2010-09-09 14:27:52

+0

运行此代码会产生错误“#1064 - 您的SQL语法有错误;请查看与您的MySQL服务器版本对应的手册,以获取在'第2行'附近使用的正确语法 - 代码 – 2010-09-09 23:32:56

1

这个怎么样,现在你不必使用自创建任何临时表的连接

DELETE u1 FROM users u1, users u2 WHERE u1.id < u2.id AND u1.email = u2.email 

要检查是否有表中的任何重复的记录

SELECT count(*) as Count, email FROM users u group by email having Count > 1