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