想要精通算法和SQL的成长之路 - 删除重复的电子邮箱(SQL)

想要精通算法和SQL的成长之路 - 删除重复的电子邮箱(SQL)

前言

想要精通算法和SQL的成长之路 - 系列导航

一. 删除重复的电子邮箱

原题链接
有一张Person表:
在这里插入图片描述

编写一个SQL删除语句来删除所有重复的电子邮件,只保留一个id最小的唯一电子邮件。

1.1 子查询(中间表相关知识点)

首先,我们可以去考虑如何拿到每种邮件最小id值:那么我们就需要用到group by 邮件 以及min(id)

select min(p.id) as d_id from Person p group by p.email

结果如下(数据量大的话会更直观一点):
在这里插入图片描述

之那么既然我们要保留这个数据,那么删除的时候,只需要反过来即可。删除不在上述返回结果集中的数据即可,即not in

DELETE  from Person where id not in (select min(p.id) as d_id from Person p group by p.email)

但是这么写却有一个问题:
在这里插入图片描述
意思是不能先select出同一表中的某些值,再update这个表。即不能依据某字段值做判断再来更新某字段的值。

因此对于这种SQL,需要用到中间表来做查询,上述SQL修改为:

DELETE from Person where id not in (
	select d_id from (
		select min(p.id) as d_id from Person p group by p.email
	) t1
)

1.2 自连接

自连接的方式很直白:

DELETE p1 FROM Person p1,
    Person p2
WHERE
    p1.email = p2.email AND p1.id > p2.id

意思是:删除p1表中的数据,需要删除的数据需要满足下面的条件。

  1. p1表和p2表的数据的邮箱一致。
  2. p1表的id要大于p2表的id

那么以p1表中的第一条数据为例:
在这里插入图片描述
p2表中没有符合条件的,因为id为1是最小的,因此该条数据不删除。
在这里插入图片描述


再以p1表中的第二条数据为例:
在这里插入图片描述
p2表中依旧没有符合条件的。


p1表中的第三条数据为例:
在这里插入图片描述
它的idp2表中的第一条数据要大,并且邮箱相同,满足条件,删除。
在这里插入图片描述

二. 总结

最终结果:

# 方案一
DELETE from Person where id not in (
	select d_id from (
		select min(p.id) as d_id from Person p group by p.email
	) t1
)
# 方案二
DELETE p1 FROM Person p1,
    Person p2
WHERE
    p1.email = p2.email AND p1.id > p2.id

知识点:不能依据某字段值做判断再来更新某字段的值。 伪代码表示就是:

update / delete xxx wherein ( selectwhere 条件)

这个时候需要运用中间表来做一次查询。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zong_0915

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值