如何统计同时拥有Code='A'和Code='B'的唯一ID?为何现有SQL返回0?
问题:统计同时包含'A'和'B'的唯一ID数量时SQL返回0的原因
需求是统计数据表中,Code列同时包含'A'和'B'值的唯一ID数量,示例数据表如下:
| ID | Code |
|---|---|
| 1 | A |
| 1 | B |
| 1 | C |
| 1 | D |
| 2 | A |
| 2 | B |
| 2 | C |
尝试了以下两条SQL语句,结果均返回0:
第一条SQL:
SELECT COUNT(DISTINCT ID) FROM tab WHERE CODE = 'A' AND CODE = 'B';
第二条SQL:
SELECT COUNT(DISTINCT ID) FROM tab AS t1 WHERE EXISTS ( SELECT 1 FROM tab WHERE ID = t1.ID AND CODE = 'A' AND CODE = 'B' );
原因分析及解决方法
为什么两条SQL都返回0
- 第一条SQL的核心问题是
WHERE CODE = 'A' AND CODE = 'B':数据表中每一行的Code字段只能存储一个值,不可能同时等于'A'和'B',这个条件永远不会匹配到任何数据,所以最终统计结果为0。 - 第二条SQL的子查询里同样用了
CODE = 'A' AND CODE = 'B',和第一条的问题完全一致——没有任何一行能满足这个矛盾条件,导致EXISTS判断始终为假,外层查询找不到符合要求的ID,结果自然也是0。
正确的实现方法
这里提供两种常用的正确写法:
方法1:分组筛选法
SELECT COUNT(ID) FROM ( SELECT ID FROM tab WHERE CODE IN ('A', 'B') GROUP BY ID HAVING COUNT(DISTINCT CODE) = 2 ) AS sub;
逻辑:先筛选出Code为'A'或'B'的所有行,按ID分组后,只保留那些分组内包含两种不同Code(即同时有A和B)的ID,最后统计这些ID的总数。
方法2:双重EXISTS验证法
SELECT COUNT(DISTINCT t1.ID) FROM tab AS t1 WHERE EXISTS ( SELECT 1 FROM tab AS t2 WHERE t2.ID = t1.ID AND t2.CODE = 'A' ) AND EXISTS ( SELECT 1 FROM tab AS t3 WHERE t3.ID = t1.ID AND t3.CODE = 'B' );
逻辑:对每个ID,分别验证是否存在对应Code为'A'的行和Code为'B'的行,只有同时满足两个条件的ID才会被统计,最后去重计数即可。
内容的提问来源于stack exchange,提问作者geek45
相关产品推荐
相关产品推荐

