CASE语句多运算符使用问题:SQL查询结果不符预期排查
问题排查与修正方案
先看你的问题:当前查询返回true不符合预期,核心是逻辑写法错误、查询范围限制错误以及子查询表名可能有误这几个问题,咱们一步步拆解修复:
原查询的核心问题
- 逻辑运算符与条件写反:你期望的是「当daughter记录超过2条且wife记录超过1条时返回false」,但原CASE里用了
OR,而且条件满足时返回true,完全和预期逻辑相反。 - 错误的条件判断:
(relation = 'daughter') > 1这个写法是错的——relation='daughter'是布尔值,SQL会把它转成1(真)或0(假),所以1>1永远为假,这部分等于没起作用。 - 查询范围被错误限制:原WHERE条件加了
relation='daughter',导致只会返回3条daughter的行,而你需要返回所有5条数据(包括wife)。 - 子查询表名可能有误:你表结构是
familyrelation,但子查询里写的是family,这会导致统计错误(如果family表不存在的话会直接报错)。
修正后的查询语句
我们用CTE先一次性统计出目标用户的wife和daughter数量,再关联查询所有行,这样既高效又逻辑清晰:
WITH family_stats AS ( SELECT -- 统计wife的数量 COUNT(CASE WHEN relation = 'wife' THEN 1 END) AS wife_count, -- 统计daughter的数量 COUNT(CASE WHEN relation = 'daughter' THEN 1 END) AS daughter_count FROM familyrelation WHERE user_id = 5 AND personid_two = 5 ) SELECT fr.user_id, fr.personid_two, fr.relation, -- 按照你的预期逻辑:满足双条件时返回false,否则true CASE WHEN fs.wife_count > 1 AND fs.daughter_count > 2 THEN 'false' ELSE 'true' END AS result FROM familyrelation fr -- 关联统计结果,确保每行都能拿到全局统计值 CROSS JOIN family_stats fs WHERE fr.user_id = 5 AND fr.personid_two = 5;
为什么这样改?
- 一次性统计提升效率:用CTE
family_stats只执行一次统计,避免原查询每行都跑子查询的冗余操作。 - 逻辑完全匹配预期:明确用
AND判断「wife>1且daughter>2」的条件,满足时返回false,和你的需求一致。 - 返回所有目标行:去掉了原WHERE里的
relation='daughter'限制,能返回所有5条符合user_id=5且personid_two=5的数据。 - 避免错误的行级别判断:不再针对当前行的
relation做错误判断,而是用全局统计值来判断整体条件。
执行这个查询后,会得到你期望的输出:
| user_id | personid_two | relation | result |
|---|---|---|---|
| 5 | 5 | wife | false |
| 5 | 5 | wife | false |
| 5 | 5 | daughter | false |
| 5 | 5 | daughter | false |
| 5 | 5 | daughter | false |
内容的提问来源于stack exchange,提问作者SRK
相关产品推荐
相关产品推荐

