case when必须嵌在select、where、order by或having中才生效;最常用的是select中生成计算字段,where中慎用因多数数据库不支持布尔表达式返回,漏写else会导致不匹配行结果为null。

SQL里CASE WHEN写在哪才生效
CASE WHEN不是独立语句,必须嵌在SELECT、WHERE、ORDER BY或HAVING里才能起作用。最常用的是放在SELECT列表中生成计算字段,比如把数值等级转成文字描述。写在WHERE里则用于动态过滤条件,但要注意:WHERE中的CASE不能返回NULL以外的值来“跳过”条件,它本质还是布尔判断。
- SELECT中用法:
CASE WHEN score >= 90 THEN 'A' ELSE 'B' END AS grade - WHERE中慎用:
WHERE CASE WHEN status = 'active' THEN created_at > '2024-01-01' ELSE TRUE END这种写法多数数据库不支持,应改用AND/OR组合 - ORDER BY中可用:
ORDER BY CASE WHEN priority = 'high' THEN 0 ELSE 1 END,控制排序优先级
CASE WHEN漏写ELSE会怎样
没写ELSE时,所有WHEN都不匹配的行,对应字段值就是NULL。这在聚合或前端展示时容易引发问题——比如统计“好评率”时,如果ELSE缺失,中评、差评全算作NULL,COUNT()会忽略它们,导致分母变小、结果虚高。
- 安全写法总带
ELSE:CASE WHEN rating > 4 THEN 'good' WHEN rating > 2 THEN 'ok' ELSE 'bad' END -
ELSE NULL显式写出更清晰,避免依赖默认行为 - 在
GROUP BY或JOIN条件中使用CASE结果时,NULL可能意外导致关联失败
简单CASE和搜索CASE的区别与选型
简单CASE(CASE column WHEN value THEN ...)只支持等值判断;搜索CASE(CASE WHEN condition THEN ...)支持任意布尔表达式。实际95%的场景都该用搜索CASE,因为业务条件很少只是“等于”。简单CASE看着短,但一旦要加>=或IS NULL就直接报错。
- 错误示范(简单CASE不支持范围):
CASE score WHEN >= 90 THEN 'A'→ 语法错误 - 正确写法(搜索CASE):
CASE WHEN score >= 90 THEN 'A' WHEN score >= 80 THEN 'B' ELSE 'C' END - 注意分支顺序:条件从上到下匹配,
score >= 80写在score >= 90前面会导致后者永远不触发
性能坑:CASE WHEN别在WHERE里套复杂子查询
有人想“动态切换查询逻辑”,在WHERE里写CASE WHEN @mode = 'by_date' THEN order_date > @dt ELSE product_id IN (SELECT id FROM hot_products) END。这种写法会让优化器无法预估执行计划,常导致全表扫描。数据库不会按@mode值分别生成两个计划,而是试图合并处理,结果往往两头不讨好。
- 真实高性能做法:用应用层拼SQL,或用
IF(MySQL)/IF EXISTS(SQL Server)做逻辑分叉 - 确需单条SQL时,拆成
UNION ALL两支,各自加明确索引提示 - CASE本身开销极小,但包裹的子查询、函数调用(如
GETDATE())会在每行重复执行,务必提前物化










