CASE WHEN 是 MySQL 中的条件表达式而非函数,支持简单CASE(等值匹配,不支持NULL直接比较)和搜索CASE(支持NULL、范围、复合条件等),执行顺序从上至下、命中即止,可用于SELECT、ORDER BY、GROUP BY、HAVING、UPDATE SET等子句,建议始终包含ELSE避免返回NULL。

CASE WHEN 在 MySQL 中不是函数,而是一个条件表达式,它不改变数据,只控制查询结果的输出逻辑。直接用就行,不需要额外安装或启用。
简单 CASE:适合等值映射,但注意 NULL 无法匹配
当你只是把某个字段的固定值转成文字(比如状态码 status = 1 → “启用”),用简单形式最清爽:
SELECT id,
CASE status
WHEN 1 THEN '启用'
WHEN 0 THEN '禁用'
ELSE '未知'
END AS status_label
FROM users;但这里有个关键限制:CASE status WHEN NULL THEN ... 永远不会命中 —— 因为 NULL = NULL 返回 UNKNOWN,不是 TRUE。所以如果 status 可能为 NULL,必须改用搜索 CASE,或显式写 WHEN status IS NULL(但它只能出现在搜索 CASE 里)。
- 只支持等值比较,不能写
WHEN status > 0 - 所有
WHEN后的值必须和status类型兼容,否则隐式转换可能出错(比如字符串字段跟数字比) -
ELSE不写会返回NULL,报表里容易漏数据,建议始终加上
搜索 CASE:处理范围、NULL、复合条件的唯一选择
真正干活时,90% 的场景都得靠搜索 CASE,因为它允许任意布尔表达式:
SELECT id, name,
CASE
WHEN score >= 90 THEN '优秀'
WHEN score >= 80 THEN '良好'
WHEN score >= 60 THEN '及格'
WHEN score IS NULL THEN '缺考'
ELSE '不及格'
END AS grade
FROM students;这个写法能自然覆盖 NULL、区间判断、AND/OR 组合。但要注意执行顺序是「从上到下、命中即停」:
- 如果把
WHEN score >= 60放在最前面,后面所有高分段都不会被判断到 -
IS NULL必须显式写出,不能依赖ELSE来兜底所有异常 —— 因为score = NULL不成立,但score IS NULL成立 - 条件中混用
IN、BETWEEN、LIKE都没问题,但别在WHEN里写子查询(MySQL 8.0+ 支持,但性能差,慎用)
CASE WHEN 能用在哪些子句里?不是所有地方都行
CASE WHEN 表达式可以出现在 SELECT、ORDER BY、GROUP BY、HAVING 和 UPDATE SET 中,但在 WHERE 里要小心:
-- ✅ 可以:用在 WHERE 中做动态过滤(但可读性差,慎用)
SELECT * FROM orders
WHERE CASE
WHEN status = '已完成' THEN amount > 100
WHEN status = '待付款' THEN amount < 50
ELSE 1=1
END;这种写法本质是把条件“包裹”进一个恒真表达式,但 MySQL 优化器很难利用索引,容易全表扫描。更推荐拆成 UNION ALL 或用标准布尔逻辑重写。
-
ORDER BY CASE很实用,比如把置顶项排前面:ORDER BY CASE WHEN is_top = 1 THEN 0 ELSE 1 END, created_at DESC -
GROUP BY CASE能实现“按区间分组”,但记得SELECT列里也要用相同CASE表达式,否则报错 -
UPDATE中用CASE批量更新不同值是安全且高效的,比多条UPDATE ... WHERE更快
类型一致性是隐形雷区
CASE WHEN 所有分支的返回值类型必须兼容,MySQL 会尝试隐式转换,但结果可能反直觉:
-- ❌ 危险:混合字符串和数字,MySQL 会把 '已发货' 转成 0,整个表达式变成数值型 CASE status WHEN 1 THEN '已支付' WHEN 2 THEN 2 ELSE '未知' END
最终所有分支都会被转成数字,'已支付' 变成 0,'未知' 也变成 0 —— 全乱了。
- 所有
THEN和ELSE的结果尽量保持同一类型:全字符串、全数字、全日期 - 不确定时,用
CAST(... AS CHAR)或CONCAT('', ...)强制转字符串 - 在 JSON 字段或 ENUM 上用
CASE,更要提前确认底层存储类型,避免隐式转换截断
实际用的时候,别纠结“该用哪种语法”,先看需求:纯等值?→ 简单 CASE;带范围、NULL、逻辑组合?→ 直接上搜索 CASE。最容易翻车的永远不是语法写错,而是忘了 NULL 不参与等值比较,以及所有分支类型没对齐。


















