US Trends

sql case when 用法

下面用通俗一点的方式,把 SQLCASE WHEN 用法系统梳理一遍,适合日常开发快速上手和查阅。

1. CASE WHEN 是什么?

CASE WHEN 可以理解为 SQL 里的 “if / else if / else” 条件表达式,用来在查询时按条件返回不同的结果,而不需要改动原表数据。

常见用途:

  • 按条件映射值(如 1/2 映射为 男/女)。
  • 根据数值区间打标签(如分数→等级、年龄段)。
  • 在聚合统计里做条件统计、条件求和。

2. 两种基本写法:简单 CASE vs 搜索 CASE

2.1 简单 CASE(Simple CASE)

语法(对“某个值”做等值匹配):

sql

CASE 表达式
    WHEN 值1 THEN 结果1
    WHEN 值2 THEN 结果2
    ...
    ELSE 默认结果
END

示例:性别编码转中文。

sql

SELECT
    user_id,
    CASE sex
        WHEN '1' THEN '男'
        WHEN '2' THEN '女'
        ELSE '其他'
    END AS sex_name
FROM user;

特点:

  • 相当于 switch...caseCASE 后面跟的是一个“表达式”或字段值,然后用 WHEN 做等号比较。
  • 适合 “1→男、2→女、3→未知” 这种枚举映射场景。

2.2 搜索 CASE(Searched CASE)

语法(每个 WHEN 都是一个完整条件):

sql

CASE
    WHEN 条件1 THEN 结果1
    WHEN 条件2 THEN 结果2
    ...
    ELSE 默认结果
END

示例:按年龄打标签。

sql

SELECT
    name,
    age,
    CASE
        WHEN age < 18 THEN '未成年'
        WHEN age BETWEEN 18 AND 60 THEN '成年人'
        ELSE '老年人'
    END AS age_group
FROM user;

特点:

  • CASE 后面不跟表达式,每个 WHEN 里是完整逻辑条件(可以用 >, <, =, BETWEEN, IN, AND, OR 等)。
  • 更灵活,基本等同于多层 if / else if / else

3. 语法结构与细节规则

3.1 基本结构

无论哪种 CASE,整体结构都是:CASE 开始,END 结束,中间若干 WHEN ... THEN ...,可选 ELSE

sql

CASE
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ...
    ELSE else_result  -- 可选
END

要点:

  • WHEN 至少 1 个,可以有很多个。
  • ELSE 可省略;如果省略且所有条件都不满足,返回 NULL
  • 整个 CASE ... END 在 SQL 中视为一个“表达式”,通常需要起别名。比如 END AS age_group

3.2 “匹配到第一个就停止”的规则

一个非常重要的点:CASE 从上到下判断,只返回第一个满足条件的结果,后面的不再执行

例子:

sql

CASE
    WHEN score >= 90 THEN 'A'
    WHEN score >= 80 THEN 'B'
    ELSE 'C'
END
  • score = 95 时,命中第一个条件(>= 90),直接返回 'A',不会再继续判断 >= 80
  • 因此,条件要从“最严格/最具体”写到“最宽松” ,否则可能出现逻辑错误。

3.3 结果值类型需要兼容

  • 同一个 CASE 的各个 THEN / ELSE 返回值,最好是相同或可隐式转换为同一类型(比如全是字符串,或者全是数字)。
  • 否则有的数据库会报类型错误,或者被强制转换成你意想不到的类型。

4. 常见使用场景示例

4.1 在 SELECT 子句中生成新字段

最常见:查询时直接生成标签字段或映射字段。

sql

SELECT
    order_id,
    amount,
    CASE
        WHEN amount >= 1000 THEN '大额订单'
        WHEN amount >= 500  THEN '中额订单'
        ELSE '小额订单'
    END AS order_level
FROM orders;

4.2 在聚合统计中做条件统计(类似条件 COUNT / SUM)

很多教程会用 CASE WHEN + 聚合函数做“条件计数/求和”。

示例:统计男女及格人数。

sql

SELECT
    COUNT(CASE WHEN sex = '1' AND score >= 60 THEN 1 END) AS male_pass,
    COUNT(CASE WHEN sex = '2' AND score >= 60 THEN 1 END) AS female_pass
FROM exam;

或用 SUM

sql

SELECT
    SUM(CASE WHEN sex = '1' AND score >= 60 THEN 1 ELSE 0 END) AS male_pass,
    SUM(CASE WHEN sex = '2' AND score >= 60 THEN 1 ELSE 0 END) AS female_pass
FROM exam;

4.3 行转列统计

在一些行转列统计里也经常用 CASE WHEN:比如把每个月的数据按列展开。

sql

SELECT
    user_id,
    SUM(CASE WHEN month = 1 THEN amount ELSE 0 END) AS m1_amount,
    SUM(CASE WHEN month = 2 THEN amount ELSE 0 END) AS m2_amount,
    ...
FROM bills
GROUP BY user_id;

这种写法本质上就是“按条件求和”,顺带把行转成列展示。

4.4 结合子查询 / 不同表条件返回不同数据

有些文章示例会写类似:如果 type=1 从 A 表取图,如果 type=2 从 B 表取图,否则用默认图。

sql

SELECT
    p.id,
    CASE p.type
        WHEN 1 THEN (SELECT b.img FROM post_book b WHERE b.pid = p.id)
        WHEN 2 THEN (SELECT t.img FROM post_tool t WHERE t.pid = p.id)
        ELSE 'default.png'
    END AS img
FROM post p;

这种写法用在复杂业务逻辑中,可以在一条 SQL 里完成“分支查询”。

5. CASE WHEN 可以出现的位置

常见位置:

  • SELECT 列中:最常见,用来生成计算列、标签列。
  • ORDER BY:实现自定义排序逻辑(如把“处理中”的排前面)。
  • GROUP BY 中有些实现也支持(但要注意规范和兼容性)。

示例:自定义排序。

sql

SELECT
    order_id,
    status
FROM orders
ORDER BY
    CASE status
        WHEN 'processing' THEN 1
        WHEN 'pending'    THEN 2
        WHEN 'done'       THEN 3
        ELSE 4
    END;

6. 常见坑与注意事项

  1. 条件顺序错误
    • 记住“命中第一个就停”,从“严”到“宽”排列条件。
  1. 忘记写 ELSE
    • 某些情况你希望未命中的记录有明确值(比如 '未知'),否则返回 NULL,可能影响后续统计。
  1. 类型不一致
    • 不要在一个 CASE 里有的 THEN 返回字符串,有的返回数字,容易出问题。
  1. 在某些数据库中不支持在 WHERE 中直接写复杂 CASE
    • 一般推荐把复杂 CASE 写在 SELECTORDER BY,如果一定要在 WHERE 中做复杂逻辑,可拆成多个条件或用子查询。

7. 小结版记忆口诀

  • 分两类:
    • 简单 CASE:CASE 字段 WHEN 值 THEN 结果 ...(类似 switch)。
* 搜索 CASE:`CASE WHEN 条件 THEN 结果 ...`(类似 if/else)。
  • 四个关键词:CASEWHENTHENELSE(可选) → END
  • 一条规则:只返回第一个符合条件的结果

如果你方便给一个具体的业务场景(比如“根据成绩分等级并统计每个等级人数”或“订单状态自定义排序”),我可以按你常用的数据库方言(MySQL / SQL Server / PostgreSQL 等)帮你写一套更贴近实战的 CASE WHEN 模板。