我正在开发一个MYSQL数据库,该数据库包含以下三列:电子邮件,姓名,姓氏。
我需要做的是重复删除我知道可以使用此功能的电子邮件(此查询仅用于排序不删除):
select distinct emails, name, surname from emails;
或
select emails, name, surname from emails group by emails having count(*) >= 2;
但是,我还需要确保当发现重复的电子邮件地址时,保留的地址是具有姓名和/或姓氏值的地址。
例如:
| id |电子邮件|名字|姓氏|
| 1 | bob@bob.com |鲍勃|保尔森|
| 2 | bob@bob.com | | |
在这种情况下,我想保留第一个结果并删除第二个结果。
我一直在研究使用'case'或'if'语句但是没有使用它们的经验。我尝试用这些语句扩展上述功能,但无济于事。
有人能指出我正确的方向吗?
PS:表中的第一列是自动递增的id值,如果有帮助
更新1:到目前为止@Bohemian的答案工作得很好,但在一个案例中有一个重复的电子邮件地址失败,在一行中它有一个名字但没有姓氏,在下一行它没有名字但有一个姓。它将保留两个记录。所有需要编辑的都是这两个记录中的一个被删除,无论哪个。
更新2:@波希米亚人的答案很棒,但经过更多测试后,我发现它有一个根本性的缺陷,它只有在有一个重复的电子邮件行时,名称和姓氏字段才有数据(如第一个)在上表中输入)。如果有重复的电子邮件但没有任何行同时填写了名称和姓氏字段,则所有这些行都将被忽略而不进行重复数据删除。
此查询的最后一步是找出如何删除不符合当前必要条件的重复项。如果一行只有名字而另一行只是姓氏,那么删除哪一行并不重要,因为电子邮件是最重要的事情。
答案 0 :(得分:4)
使用mysql multiple-table delete syntax:
这很容易delete b
from mytable a
join mytable b
on a.email = b.email
and a.id != b.id
where a.name is not null
and a.surname is not null
答案 1 :(得分:4)
您可以使用此DELETE查询,该查询是通用的,可以轻松调整以支持更多字段:
DELETE tablename.*
FROM
tablename LEFT JOIN (
SELECT MIN(id) min_id
FROM
tablename t INNER JOIN (
SELECT
emails, MAX((name IS NOT NULL) + (surname IS NOT NULL)) max_non_nulls
FROM
tablename
GROUP BY
emails) m
ON t.emails=m.emails
AND ((t.name IS NOT NULL) + (t.surname IS NOT NULL))=m.max_non_nulls
GROUP BY
t.emails) ids
ON tablename.id=ids.min_id
WHERE
ids.min_id IS NULL
请参阅小提琴here。
此查询返回每封电子邮件的最大非空字段数:
SELECT
emails,
MAX((name IS NOT NULL) + (surname IS NOT NULL)) max_non_nulls
FROM
tablename
GROUP BY
emails
然后我使用tablename加入此查询,以获取具有最大非空字段数的每封电子邮件的最小ID:
SELECT MIN(id) min_id
FROM
tablename t INNER JOIN (
SELECT
emails, MAX((name IS NOT NULL) + (surname IS NOT NULL)) max_non_nulls
FROM
tablename
GROUP BY
emails) m
ON t.emails=m.emails
AND ((t.name IS NOT NULL) + (t.surname IS NOT NULL))=m.max_non_nulls
GROUP BY
t.emails
然后我将删除所有具有此查询未返回ID的行。
答案 2 :(得分:0)
删除包含重复电子邮件ID的记录
delete
from duplicate_email where id in(
select id from (
select id, email from duplicate_email group by email having count(id) > 1) as id
)
但是有一个问题是你可以删除那些只有一个重复邮件的记录,即两个相同的电子邮件,但如果有三个或更多,你可以重复这个查询,直到你删除零记录