SQL技术问询:如何筛选name与code字段值相同但address字段值不同的重复数据行
筛选name和code重复但address不同的数据行
没问题,咱们来一步步解决这个需求!首先先明确下场景:
假设我们有如下结构的表:
| id | name | address | code |
|---|---|---|---|
| 101 | joe smith | 1 long road | SC1 |
| 102 | joe smith | 6 long road | SC1 |
| 103 | amy hughes | 5 hillside lane | SC5 |
| 104 | amy hughes | 5 hillside lane | SC5 |
我们要找的是name和code字段值完全相同,但address字段值不一样的数据行。你之前的查询是用来筛选name、address、code三者都重复的记录:
SELECT name, address, code, count(*) FROM table_name GROUP BY 1,2,3 HAVING count(*) >1;
当然可以基于这个思路扩展出符合需求的查询,下面给你两种实用的方法:
方法一:子查询筛选目标分组后关联
核心思路是先定位到那些name+code组合下存在多个不同address的分组,再关联回原表拿到完整数据:
SELECT t.id, t.name, t.address, t.code FROM table_name t JOIN ( -- 先找出name和code相同,但存在多种address的组合 SELECT name, code FROM table_name GROUP BY name, code HAVING COUNT(DISTINCT address) > 1 ) AS sub ON t.name = sub.name AND t.code = sub.code;
在你的示例数据里,这个查询会精准返回id为101和102的两行,完全符合预期。
方法二:窗口函数写法(更简洁)
如果你的数据库支持窗口函数(比如PostgreSQL、MySQL 8+、SQL Server这些主流数据库都支持),可以用更直观的方式实现:
SELECT id, name, address, code FROM ( SELECT id, name, address, code, -- 统计当前name+code分组下不同address的数量 COUNT(DISTINCT address) OVER (PARTITION BY name, code) AS addr_count FROM table_name ) AS sub WHERE addr_count > 1;
这里用PARTITION BY name, code把数据按name和code分组,窗口函数会计算每个分组里不同address的数量,最后只保留数量大于1的行就行。
补充说明
你之前的查询是按name, address, code三个字段分组,只能找出三者完全重复的记录(比如示例里的103和104)。而我们的需求需要把分组维度改成name+code,同时关注这个分组下address的唯一性数量,这样就能精准筛选出目标数据啦。
内容的提问来源于stack exchange,提问作者nimgwfc
相关产品推荐
相关产品推荐

