【mysql】SQL自连接查询:轻松找出重复数据中的最大ID记录

SQL自连接查询:轻松找出重复数据中的最大ID记录

你是否曾在编写SQL查询时,遇到过需要从同一张表中查找重复记录,并只保留其中某一条的情况?本文将通过一个典型示例,详细解析如何使用自连接(Self-Join) 高效解决这类问题。


🧠 理解自连接查询

自连接查询
同一张表视为两个别名: p1, p2
筛选条件1: p1.Email = p2.Email
筛选条件2: p1.Id > p2.Id
找出邮箱相同的记录
排除自身比较, 保留ID更大的记录
最终结果: 重复邮箱中ID最大的记录

📌 示例场景与SQL语句

假设我们有一张 Person 表,结构如下:

IdEmail
1a@example.com
2b@example.com
3a@example.com
4c@example.com

我们希望找出所有重复的邮箱,并只保留 Id 最大 的那一条记录。

使用的SQL语句如下:

SELECT p1.*
FROM Person p1, Person p2
WHERE p1.Email = p2.Email 
  AND p1.Id > p2.Id;

🔍 分步解析执行过程

第一步:自连接生成所有组合

Person 表视为两个别名表 p1p2,进行笛卡尔积连接,生成所有可能的行组合(共 n × n 行)。

p1p2
(1, a@…)(1, a@…)
(1, a@…)(2, b@…)
(1, a@…)(3, a@…)

第二步:应用筛选条件

条件一:p1.Email = p2.Email

只保留邮箱相同的行组合。

条件二:p1.Id > p2.Id

进一步筛选出 p1 的 Id 大于 p2 的 Id 的组合,目的是:

  • 排除自己与自己比较(Id 相等)
  • 只保留“后出现”的记录(Id 更大)

第三步:最终结果

符合条件的记录即为重复邮箱中 Id 最大的那条。


✅ 结果示例

执行上述查询后,将返回:

IdEmail
3a@example.com

因为:

  • a@example.com 是重复邮箱
  • Id = 3 是重复中最大的 Id

📖 总结表格:关键知识点

概念说明示例
自连接将同一张表视为两个不同的表进行连接FROM Person p1, Person p2
重复筛选通过字段相等条件找出重复项p1.Email = p2.Email
排除自身比较使用 Id 大小比较避免同一行比较,并保留“后出现”的记录p1.Id > p2.Id
适用场景去重、保留最新/最大ID记录、查找重复数据等用户表、订单表、日志表等均有应用场景

💡 常见疑问解答

❓ 为什么用 > 而不用 >=

  • 使用 > 可以排除自己与自己比较(Id 相等的情况)
  • 使用 >= 会包含自身,导致结果中出现不必要的重复

❓ 是否可以用其他方式实现?

是的,还可以使用 GROUP BY + HAVINGROW_NUMBER() 窗口函数实现类似功能,但自连接在理解上更直观,且在某些数据库中有较好的性能。


🎯 一句话总结

通过自连接和条件 p1.Email = p2.Email AND p1.Id > p2.Id,可以高效找出重复数据中 Id 最大的记录,适用于多种去重场景。


如果你也遇到过类似的数据去重问题,不妨尝试使用自连接查询,简洁又高效!欢迎在评论区分享你的使用经验或疑问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值