SQL中WHERE子句用CASE与AND/OR返回结果不同的原因
核心原因
CASE表达式缺省ELSE分支返回NULL,而WHERE子句仅会保留条件判断结果为TRUE的行,两条查询的逻辑本质并不等价,具体差异如下:
- 未显式声明ELSE分支的CASE表达式,在不匹配任何WHEN条件时,SQL默认返回
NULL - WHERE子句过滤规则为仅保留条件结果为布尔TRUE的行,
FALSE和NULL都会触发行过滤
两个查询的逻辑差异
查询1执行逻辑
你编写的CASE表达式仅对美国客户做判断:
- 当客户国家为
US时,CASE返回customer.tax_exempt <> 'f'的布尔结果,仅结果为TRUE时行才会被保留 - 当客户国家不为
US时,CASE无匹配WHEN分支,直接返回NULL触发过滤,所有非美国客户行都会被排除
因此查询1最终仅返回美国客户中tax_exempt不为f的行。
查询2执行逻辑
替换后的条件customer.country <> 'US' OR customer.tax_exempt <> 'f'为标准布尔逻辑判断:
- 只要客户国家不为
US,第一个判断分支就为TRUE,整行直接满足条件被保留 - 当客户国家为
US时,需要满足tax_exempt <> 'f'才会被保留
因此查询2最终返回所有非美国客户 + 美国客户中tax_exempt不为f的行,和你观测到的结果完全一致。
等价改写参考
如果希望查询1实现和查询2一致的逻辑,补全CASE的ELSE分支即可:
AND ( CASE WHEN customer.country = 'US' THEN customer.tax_exempt <> 'f' ELSE TRUE END )
如果希望查询2实现和查询1一致的逻辑,调整条件为:
AND customer.country = 'US' AND customer.tax_exempt <> 'f'
内容的提问来源于stack exchange,提问作者Trouble Bucket
相关产品推荐
相关产品推荐

