我有一张数据表,其中包含许多用户提交的重复条目。
我想根据字段subscriberEmail
删除所有重复行,只保留原始提交。
换句话说,我想查找所有重复的电子邮件,并删除这些行,只保留原始数据。
如何在不交换表的情况下执行此操作?
我的表中包含每行的唯一标识符。
我有一张数据表,其中包含许多用户提交的重复条目。
我想根据字段subscriberEmail
删除所有重复行,只保留原始提交。
换句话说,我想查找所有重复的电子邮件,并删除这些行,只保留原始数据。
如何在不交换表的情况下执行此操作?
我的表中包含每行的唯一标识符。
因为您将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值的记录。您真正想要的数据,即唯一的电子邮件地址(带有最低的Id),将不是x的一部分,也不会被删除。x中的唯一记录将是具有较高ID的重复记录(电子邮件地址)。
在这种情况下,连接和where子句可以合并:
delete x
from myTable x
join myTable z
on x.subscriberEmail = z.subscriberEmail
and x.id > z.id
为了防止重复,考虑将subscriberEmail列设为唯一索引列。
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
delete from my_table where id in (
select id from (
select id from my_table a group by subscriberEmail having count(*) > 1
) b
);