如何筛选存在B或null历史状态的status为A的app_id数据
解决方案:筛选符合条件的app_id
输入表
| app_id | status | modified_date |
|---|---|---|
| 1 | A | 2022-10-23 |
| 1 | B | 2022-10-10 |
| 1 | null | 2022-10-05 |
| 2 | A | 2022-11-10 |
| 2 | B | 2022-11-03 |
| 3 | A | 2022-12-15 |
需求明确
需要提取同时满足以下两个条件的app_id:
- 该
app_id下存在至少一条status = 'A'的记录 - 同一
app_id下存在至少一条status = 'B'或status IS NULL的记录
排除仅存在status = 'A'的app_id(比如示例中的app_id 3)
可行的SQL写法
方法一:GROUP BY + HAVING 聚合筛选
这是最直观的写法,通过分组后聚合统计来判断条件:
SELECT app_id FROM your_table_name GROUP BY app_id HAVING -- 统计当前app_id下status为A的行数,大于0说明存在 SUM(CASE WHEN status = 'A' THEN 1 ELSE 0 END) > 0 -- 统计当前app_id下status为B或null的行数,大于0说明存在 AND SUM(CASE WHEN status = 'B' OR status IS NULL THEN 1 ELSE 0 END) > 0;
方法二:EXISTS 子查询验证
适合数据量较大的场景,利用子查询快速验证关联条件,最后去重:
SELECT DISTINCT t1.app_id FROM your_table_name t1 WHERE t1.status = 'A' AND EXISTS ( SELECT 1 FROM your_table_name t2 WHERE t2.app_id = t1.app_id AND (t2.status = 'B' OR t2.status IS NULL) );
方法三:子查询筛选后关联
和方法二逻辑类似,先筛选出存在B/null的app_id,再关联到有A的记录:
SELECT DISTINCT t.app_id FROM your_table_name t JOIN ( SELECT app_id FROM your_table_name WHERE status = 'B' OR status IS NULL ) sub ON t.app_id = sub.app_id WHERE t.status = 'A';
以上三种写法都能得到示例中的预期结果:app_id 1和app_id 2。
内容的提问来源于stack exchange,提问作者Rafał
相关产品推荐
相关产品推荐

