首页/数据/数据库速查/CASE WHEN 条件表达式
SQL 语法52 条

CASE WHEN 条件表达式

在 SQL 内做分支:简单 CASE 对值比较,搜索 CASE 对条件判断;常用于分桶统计与结果转义,也是行列转换的基础。

数据库速查数据更新于 2026-10-13

CASE WHEN 是什么

CASE WHEN 在 SQL 内做条件分支,有两种形式:简单 CASE 对某个表达式取值比较,搜索 CASE 对条件逐条判断。分支从上到下匹配,命中即返回,因此条件顺序会直接影响结果。它常用于分桶统计、状态映射与行列转换,是把逻辑下沉到 SQL 的常用手段。要记住 CASE 是表达式而不是语句,可以出现在 SELECT、WHERE、ORDER BY、GROUP BY 以及各种聚合函数内部。写分桶统计时先想清楚每个桶的边界是否包含等号,边界写错产生的报表偏差往往很难被发现。

基本信息

用途条件分支与结果映射
两种形式CASE 值 WHEN … 与 CASE WHEN 条件 …
分支规则从上到下匹配,命中即返回
嵌套表达式内可以继续嵌套 CASE
常用搭配NULLIF、IFNULL、COALESCE 一起处理空值

典型使用场景

  • 把金额或分数分桶,生成区间统计
  • 把状态码映射成可读文案
  • 配合聚合函数做行列转换(透视)
  • 给报表增加条件汇总列
  • 在计算中处理 NULL 与默认值

分桶与透视

分桶与透视
SELECT
  CASE WHEN amount >= 1000 THEN 'high'
       WHEN amount >= 100  THEN 'mid'
       ELSE 'low' END AS bucket,
  COUNT(*) AS cnt
FROM orders
GROUP BY bucket;

-- 行列转换:一次扫描算出多列
SELECT user_id,
  SUM(CASE WHEN status='paid'   THEN amount ELSE 0 END) AS paid_amt,
  SUM(CASE WHEN status='refund' THEN amount ELSE 0 END) AS refund_amt
FROM orders GROUP BY user_id;

两种形式对比

形式写法适用场景
简单 CASECASE 列 WHEN 值 THEN …只做等值比较
搜索 CASECASE WHEN 条件 THEN …支持任意条件与区间判断
分支顺序从上到下匹配范围条件要从窄到宽书写
ELSE兜底分支不写时未命中返回 NULL
嵌套表达式内再套 CASE注意可读性,必要时拆子查询
忘记 ELSE 时未命中分支返回 NULL,参与 SUM 或 AVG 会静默把结果变成 NULL。统计类 SQL 写完先抽查几行原始数据,确认兜底分支完整。
把 CASE 挂在索引列上做条件判断或排序,会让索引失效、退化为全表扫描;把分支计算放在 SELECT 列表或聚合里才划算。
用 SUM(CASE WHEN …) 做透视比多次查询更高效:一次扫描就能生成多列统计,避免对同一张大表反复访问。列数很多时要注意 SQL 长度与可读性,必要时拆成两次查询。

易错点

  • 忘记 ELSE 导致未命中返回 NULL:求和与平均值静默出错
  • 条件顺序从宽到窄书写:后面的分支永远命中不到
  • 在 WHERE 或 ORDER BY 里使用 CASE:索引基本失效
  • 把复杂业务逻辑全塞进 CASE:SQL 难以维护,应拆分或移到应用层
  • 分桶时条件顺序从宽到窄:所有数据都落进第一个桶,统计结果整体失真

数据来源与参考

  • MySQL 8.0 Reference Manual: CASE Expression

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌