CASE WHEN有两种写法:1.简单CASE仅支持等值判断,不能用>、IS NULL或函数;2.搜索CASE支持任意布尔表达式,业务中几乎全用此模式。
CASE WHEN 不是万能开关,嵌套过深或漏写 ELSE 会直接导致 NULL 值污染结果,尤其在聚合或 JOIN 场景下容易静默出错。
简单 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 gradeFROM users;
ELSE:不满足任何条件时返回 NULL,不是空字符串也不是 0WHEN 子句按顺序执行,第一个为 true 就终止,后续不判断THEN 返回值类型应尽量一致,否则数据库可能隐式转换(如把字符串和数字混用会触发警告或截断)常见错误是把 CASE WHEN 放在 GROUP BY 外却想按分类统计——必须确保分组依据和聚合逻辑对齐。
例如统计各年龄段用户数,不能只在 SELECT 里写 CASE,还要在 GROUP BY 中复现相同逻辑:
SELECT CASE WHEN age < 18 THEN 'under_18' WHEN age BETWEEN 18 AND 35 THEN 'young_adult' ELSE 'senior' END AS age_group, COUNT(*) AS cntFROM usersGROUP BY CASE WHEN age < 18 THEN 'under_18' WHEN age BETWEEN 18 AND 35 THEN 'young_adult' ELSE 'senior' END;
GROUP BY age_group),但 SQLite 和旧版 MySQL 不行,得重复表达式CASE 里用了不可索引的函数(如 UPPER(name)),会影响 GROUP BY 性能SUM(CASE ...) 里漏写 ELSE 0,否则 SUM 会跳过 NULL 导致结果偏小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 索引最常被忽略的是 NULL 处理:所有分支都未命中时默认返回 NULL,而 NULL 在 COUNT、SUM、JOIN 关联中行为特殊——它不会报错,但会让结果偏离预期。写完 CASE 后,先用 WHERE result_column IS NULL 查一遍,比上线后排查数据异常快得多。