case when有两种写法:1.简单case仅支持等值判断,不能用>、is null或函数;2.搜索case支持任意布尔表达式,业务中几乎全用此模式。

CASE WHEN 不是万能开关,嵌套过深或漏写 ELSE 会直接导致 NULL 值污染结果,尤其在聚合或 JOIN 场景下容易静默出错。
CASE WHEN 的两种写法区别在哪?
简单 CASE(CASE column WHEN value THEN ...)只支持等值判断,不能用 >、IS NULL 或函数;搜索 CASE(CASE WHEN condition THEN ...)才真正灵活,所有布尔表达式都可写。
实际几乎全用搜索 CASE,因为业务逻辑极少只靠“等于”就能覆盖。比如判断用户等级:
SELECT
name,
CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
WHEN score >= 60 THEN 'C'
ELSE 'F'
END AS grade
FROM users;
- 漏写
ELSE:不满足任何条件时返回NULL,不是空字符串也不是 0 -
WHEN子句按顺序执行,第一个为 true 就终止,后续不判断 - 所有
THEN返回值类型应尽量一致,否则数据库可能隐式转换(如把字符串和数字混用会触发警告或截断)
在 GROUP BY 或聚合函数里怎么安全用 CASE WHEN?
常见错误是把 CASE WHEN 放在 GROUP BY 外却想按分类统计——必须确保分组依据和聚合逻辑对齐。
例如统计各年龄段用户数,不能只在 SELECT 里写 CASE,还要在 GROUP BY 中复现相同逻辑:
SELECT
CASE
WHEN age
- MySQL 8.0+ 和 PostgreSQL 允许用列别名(如
GROUP BY age_group),但 SQLite 和旧版 MySQL 不行,得重复表达式 - 如果
CASE里用了不可索引的函数(如UPPER(name)),会影响 GROUP BY 性能 - 聚合中嵌套 CASE 时,避免在
SUM(CASE ...)里漏写ELSE 0,否则SUM会跳过 NULL 导致结果偏小
为什么在 WHERE 或 ON 条件里少用 CASE WHEN?
WHERE 子句本质是过滤,而 CASE WHEN 是表达式计算——它无法利用索引,还可能让优化器放弃执行计划缓存。
比如想查“VIP 用户或下单超 5 次的普通用户”,写成:
WHERE
CASE
WHEN user_type = 'vip' THEN 1
WHEN order_count > 5 THEN 1
ELSE 0
END = 1
不如直接写:
WHERE user_type = 'vip' OR order_count > 5
- 前者强制全表扫描,后者可能走
user_type或order_count索引 - ON 子句中同理,JOIN 条件里塞 CASE 容易让连接变慢且难以调试
- 真需要动态条件(如多租户字段名不同),优先考虑应用层拼 SQL 或用 UNION 分拆,而不是硬塞 CASE
最常被忽略的是 NULL 处理:所有分支都未命中时默认返回 NULL,而 NULL 在 COUNT、SUM、JOIN 关联中行为特殊——它不会报错,但会让结果偏离预期。写完 CASE 后,先用 WHERE result_column IS NULL 查一遍,比上线后排查数据异常快得多。











