SQL SELECT查询需求:筛选仅含A1、A2且无A3的用户对应行
SQL查询解决方案
你可以根据你使用的数据库类型选择以下任意一种兼容写法:
通用兼容写法(支持所有主流SQL数据库)
先通过子查询筛选出符合条件的用户名,再关联原表获取对应用户的全部记录:
SELECT t.Name, t.Type FROM 你的表名 t INNER JOIN ( SELECT Name FROM 你的表名 GROUP BY Name HAVING SUM(CASE WHEN Type = 'A1' THEN 1 ELSE 0 END) >= 1 AND SUM(CASE WHEN Type = 'A2' THEN 1 ELSE 0 END) >= 1 AND SUM(CASE WHEN Type = 'A3' THEN 1 ELSE 0 END) = 0 ) qualified ON t.Name = qualified.Name;
简洁写法(适配MySQL)
利用MySQL布尔表达式返回1/0的特性简化判断:
SELECT Name, Type FROM 你的表名 WHERE Name IN ( SELECT Name FROM 你的表名 GROUP BY Name HAVING MAX(Type = 'A1') = 1 AND MAX(Type = 'A2') = 1 AND MAX(Type = 'A3') = 0 );
窗口函数写法(支持PostgreSQL、MySQL 8.0+、SQL Server等支持窗口函数的数据库)
仅需一次表扫描即可完成统计,性能更优:
WITH user_stat AS ( SELECT Name, Type, COUNT(CASE WHEN Type = 'A1' THEN 1 END) OVER(PARTITION BY Name) AS has_a1, COUNT(CASE WHEN Type = 'A2' THEN 1 END) OVER(PARTITION BY Name) AS has_a2, COUNT(CASE WHEN Type = 'A3' THEN 1 END) OVER(PARTITION BY Name) AS has_a3 FROM 你的表名 ) SELECT Name, Type FROM user_stat WHERE has_a1 >= 1 AND has_a2 >= 1 AND has_a3 = 0;
逻辑说明
以上所有写法核心逻辑一致:
- 先按用户名分组统计每个用户持有的Type类型
- 筛选同时满足「持有A1」「持有A2」「不持有A3」三个条件的用户
- 最终返回这些用户的全部对应记录
使用时将SQL中的你的表名替换为实际的表名即可得到预期结果。
内容的提问来源于stack exchange,提问作者Wirley Daviondyll G. Valdez
相关产品推荐
相关产品推荐

