MySQL中CASE WHEN有两种语法:搜索CASE支持任意条件判断,如CASE WHEN score>=90 THEN 'A';简单CASE仅用于等值匹配,如CASE status WHEN 1 THEN '启用'。广泛用于SELECT生成标签、WHERE过滤、ORDER BY排序、GROUP BY分组及UPDATE条件更新。

在 MySQL 中,CASE WHEN 是实现查询中条件判断最常用、最灵活的方式,它能在 SELECT、ORDER BY、HAVING 甚至 UPDATE 语句里动态生成字段值或控制执行逻辑。
基本语法结构要分清两种写法
MySQL 支持两种 CASE 语法:简单 CASE 和搜索 CASE。日常多数场景用后者(即带 WHEN condition THEN result 的形式),因为它支持任意布尔表达式:
-
搜索 CASE(推荐):
CASE WHEN score >= 90 THEN 'A' WHEN score >= 80 THEN 'B' ELSE 'C' END AS grade -
简单 CASE(类比 switch):
CASE status WHEN 1 THEN '启用' WHEN 0 THEN '禁用' ELSE '未知' END—— 仅适用于等值判断,不支持 >、IS NULL 等
在 SELECT 中动态生成分类字段
这是最典型用法:把数值/状态字段转为可读性更强的文本标签。例如统计用户等级:
SELECT
name,
age,
CASE
WHEN age < 18 THEN '未成年'
WHEN age BETWEEN 18 AND 60 THEN '成年人'
ELSE '老年人'
END AS age_group
FROM users;注意:CASE 表达式本身就是一个“值”,可直接起别名、参与计算、嵌套使用(比如 CASE WHEN (CASE ...) = 'A' THEN ...),但嵌套过深会降低可读性,建议拆解或用视图封装。
配合聚合函数做条件统计
想统计“支付成功订单数”“未支付订单数”,不用写多个子查询,用 SUM(CASE WHEN ... THEN 1 ELSE 0 END) 一行搞定:
SELECT COUNT(*) AS total_orders, SUM(CASE WHEN status = 'paid' THEN 1 ELSE 0 END) AS paid_count, SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS pending_count, AVG(CASE WHEN status = 'paid' THEN amount END) AS avg_paid_amount -- 注意:此处 NULL 会被自动忽略 FROM orders;
关键点:
– SUM + CASE 是计数惯用写法;
– AVG 或 MAX 等聚合函数对 CASE 返回的 NULL 自动跳过,无需额外过滤;
– 若需统计占比,可直接用 SUM(...) / COUNT(*) 计算。
在 ORDER BY 和 WHERE 中灵活控制排序与筛选
CASE 不只用于输出,还能影响查询行为:
-
自定义排序:
ORDER BY CASE type WHEN 'vip' THEN 1 WHEN 'normal' THEN 2 ELSE 3 END,让 VIP 用户排最前 -
条件筛选(慎用):
WHERE CASE WHEN is_deleted = 0 THEN id ELSE NULL END IS NOT NULL—— 这种写法不如直接写is_deleted = 0高效,仅在复杂动态条件(如多参数组合)且无法用 OR 优化时考虑
提醒:WHERE 中过度依赖 CASE 可能导致索引失效,优先用标准布尔逻辑;ORDER BY 中的 CASE 则常用于业务排序需求,只要结果集不大,性能影响有限。
掌握这几种用法,就能覆盖绝大多数基于字段值做逻辑分支的查询场景。核心是理解 CASE 本质是一个返回标量值的表达式,而不是流程控制语句——它没有“跳出”或“中断”,每个 WHEN 是独立判断,顺序匹配,遇到第一个为 TRUE 的就返回对应结果,其余不再执行。


















