SQL实现:筛选关联非唯一TrackingNumber的三列组合
问题说明
现有测试数据表结构及样例数据如下:
| ItemID | ItemName | ItemBatch | TrackingNumber |
|---|---|---|---|
| a | bag | 1 | 498239 |
| a | bag | 1 | 498239 |
| a | bag | 1 | 958103 |
| b | paper | 2 | 123444 |
| b | paper | 2 | 123444 |
查询目标:筛选出ItemID、ItemName、ItemBatch三列值完全相同,但关联的TrackingNumber存在多个不同值的组合。以上述样例为例,a + bag + 1组合对应2个不同运单号,符合命中规则;b + paper + 2组合所有运单号均为123444,需要排除。
查询实现
根据你需要返回的结果不同,有两种常用写法:
1. 返回符合条件的全量明细记录
如果需要拿到命中组合对应的所有原始行数据,可以先通过分组聚合筛出符合条件的三列组合,再关联原表取全量字段:
SELECT t.* FROM 你的表名 t JOIN ( SELECT ItemID, ItemName, ItemBatch FROM 你的表名 GROUP BY ItemID, ItemName, ItemBatch HAVING COUNT(DISTINCT TrackingNumber) > 1 ) valid_group ON t.ItemID = valid_group.ItemID AND t.ItemName = valid_group.ItemName AND t.ItemBatch = valid_group.ItemBatch;
针对样例数据执行后,会返回a + bag + 1对应的全部3条记录。
2. 仅返回符合条件的三列组合
如果不需要明细数据,只需要拿到存在多运单号的三列组合本身,直接分组筛选即可,查询效率更高:
SELECT ItemID, ItemName, ItemBatch FROM 你的表名 GROUP BY ItemID, ItemName, ItemBatch HAVING COUNT(DISTINCT TrackingNumber) > 1;
针对样例数据执行后,仅会返回a | bag | 1这一条组合结果。
踩坑提示:不要直接写
COUNT(TrackingNumber) > 1作为判断条件,这种写法会统计TrackingNumber的总出现次数,会把b + paper + 2这种运单号重复但值完全一致的组合误判为符合条件,必须加DISTINCT对TrackingNumber去重后再计数。
内容的提问来源于stack exchange,提问作者Joe Defill
相关产品推荐
相关产品推荐

