编写含条件判断的SQL查询:按客户筛选OS数据
按客户维度筛选OS记录:优先返回STATUS_ID=2,无则返回STATUS_ID=1
需求说明
按客户维度筛选OS表数据:
- 若客户存在
STATUS_ID为2的记录,返回该客户所有STATUS_ID=2的记录 - 若客户没有
STATUS_ID为2的记录,返回该客户STATUS_ID=1的记录
现有数据
| ID | STATUS_ID | CLIENT |
|---|---|---|
| 1 | 2 | 1 |
| 2 | 1 | 1 |
| 3 | 2 | 2 |
| 4 | 1 | 3 |
期望结果
| ID | STATUS_ID | CLIENT |
|---|---|---|
| 1 | 2 | 1 |
| 3 | 2 | 2 |
| 4 | 1 | 3 |
原查询的错误分析
你写的查询核心问题是字段名不匹配:原表中客户字段名为CLIENT,但子查询里误用了client_id,导致表关联逻辑完全失效。另外,子查询里返回id没必要,用1更高效。
修正后的解法
解法一:修正EXISTS关联逻辑
SELECT * FROM os WHERE status_id = 2 OR ( status_id = 1 AND NOT EXISTS ( SELECT 1 FROM os AS o WHERE o.CLIENT = os.CLIENT AND o.status_id = 2 ) )
这里给子查询的表加了别名o,避免和外层表的字段混淆,同时修正了字段名错误,确保关联逻辑正确。
解法二:用窗口函数实现(更灵活)
如果需要处理更复杂的优先级排序,或者要确保每个客户只返回一条最高优先级记录,窗口函数是更好的选择:
WITH ranked_os AS ( SELECT *, -- 给STATUS_ID=2的记录标记最高优先级(rn=1) ROW_NUMBER() OVER ( PARTITION BY CLIENT ORDER BY CASE status_id WHEN 2 THEN 1 ELSE 2 END ) AS rn FROM os ) SELECT ID, STATUS_ID, CLIENT FROM ranked_os WHERE rn = 1;
如果一个客户有多个STATUS_ID=2的记录,想返回所有的话,把ROW_NUMBER()换成RANK()即可。
内容的提问来源于stack exchange,提问作者Bruno
相关产品推荐
相关产品推荐

