如何筛选包含Product1及其他产品的同Id数据?
问题描述
我有一张包含Id和ProductName列的表,样本数据如下:
| Id | ProductName |
|---|---|
| ABC123 | Product1 |
| ABC123 | Product2 |
| XYZ345 | Product1 |
| PQR123 | Product1 |
| MNP789 | Product3 |
| EFG456 | Product1 |
| EFG456 | Product6 |
| EFG456 | Product7 |
| JKL909 | Product8 |
| JKL909 | Product8 |
| JKL909 | Product8 |
| DBC778 | Product9 |
| DBC778 | Product10 |
需要筛选出所有满足同一Id下同时存在Product1和其他产品的行,期望输出如下:
| Id | ProductName |
|---|---|
| ABC123 | Product1 |
| ABC123 | Product2 |
| EFG456 | Product1 |
| EFG456 | Product6 |
| EFG456 | Product7 |
即分组筛选出包含Product1及其他产品的Id对应的所有记录。我尝试了以下查询但未得到预期结果:
select Id, ProductName from tbl1 group by Id, ProductName having count(ProductName) > 1
解决方案
你的原查询逻辑有误:按Id和ProductName分组后,having count(ProductName) > 1是筛选同一个ID下同一产品重复出现的记录(比如JKL909的Product8),和需求完全不符。
要实现目标,核心是先识别出同时包含Product1和其他产品的ID,再获取这些ID对应的所有行,以下是几种可行写法:
方法1:子查询筛选符合条件的ID
SELECT Id, ProductName FROM tbl1 WHERE Id IN ( SELECT Id FROM tbl1 GROUP BY Id HAVING MAX(CASE WHEN ProductName = 'Product1' THEN 1 ELSE 0 END) = 1 -- 该ID下存在Product1 AND COUNT(DISTINCT ProductName) > 1 -- 该ID下至少有两种不同产品(即包含其他产品) )
方法2:窗口函数实现
WITH IdStats AS ( SELECT Id, ProductName, -- 标记该ID是否包含Product1 MAX(CASE WHEN ProductName = 'Product1' THEN 1 ELSE 0 END) OVER (PARTITION BY Id) AS has_product1, -- 统计该ID下不同产品的数量 COUNT(DISTINCT ProductName) OVER (PARTITION BY Id) AS distinct_product_count FROM tbl1 ) SELECT Id, ProductName FROM IdStats WHERE has_product1 = 1 AND distinct_product_count > 1
方法3:关联查询
SELECT t1.Id, t1.ProductName FROM tbl1 t1 JOIN ( SELECT Id FROM tbl1 GROUP BY Id HAVING EXISTS (SELECT 1 FROM tbl1 t2 WHERE t2.Id = tbl1.Id AND t2.ProductName = 'Product1') AND EXISTS (SELECT 1 FROM tbl1 t3 WHERE t3.Id = tbl1.Id AND t3.ProductName != 'Product1') ) t4 ON t1.Id = t4.Id
以上三种方法都能精准筛选出符合要求的记录,你可以根据自己使用的数据库特性选择合适的写法。
内容的提问来源于stack exchange,提问作者Santosh
相关产品推荐
相关产品推荐

