有时需要将存储的值(或即将存储的值)从一种表示形式转换为另一种形式。例如,一个列 status 的合法值是从 0 到 9,但最终用户需要收到解释这些数值含义的简短字符串,例如:'ordered''delivered''back delivery''out of stock' 等。推荐的做法是使用一个单独的表,将数值映射到说明性字符串。不过,应用开发人员可能更倾向于在应用服务器内解决该问题。

CASE 表达式 是 SQL 中用于处理这种情况的一个方法,可以在 SELECTINSERTUPDATE 命令中使用,并解决类似问题。在此页,我们主要讨论它在 SELECT 命令中的使用。相比推荐的单独表映射方式,CASE 表达式更加灵活(但在某些情况下,这种灵活性可能并不是优势)。


两个示例

示例 1:简单 CASE 表达式

-- 技术术语:"simple case"
-- 将 contact_type 翻译为可读的形式
SELECT id,
       CASE contact_type
         WHEN 'fixed line' THEN 'Phone'
         WHEN 'mobile'     THEN 'Phone'
         ELSE                   'Not a telephone number'
       END AS 'contact_type',
       contact_value
FROM   contact;
  • 语法说明
    CASE 表达式从关键字 CASE 开始,到 END 关键字结束。
    该表达式指定一个列名 contact_type,然后依次检查 WHEN/THEN 条件,最后可以通过 ELSE 指定默认值。如果未匹配且没有 ELSE,将返回 NULL

示例 2:搜索型 CASE 表达式

-- 技术术语:"searched case"
-- 根据体重分级
SELECT firstname,
       lastname,
       weight,
       CASE
         WHEN (weight IS NULL OR weight = 0) THEN 'weight is unknown'
         WHEN weight < 40                    THEN 'lightweight'
         WHEN weight BETWEEN 40 AND 85       THEN 'medium'
         ELSE                                     'heavyweight'
       END AS 'weight_class'
FROM   person;
  • 语法说明
    搜索型 CASE 表达式的关键在于 CASE 和首个 WHEN 之间没有指定列名。
    在此变体中,每个 WHEN 后必须是一个完整的逻辑表达式,可以使用比较操作符、布尔操作符,甚至跨列或函数调用。

语法

简单 CASE 表达式

CASE <column_name>
  WHEN <expression_1> THEN <result_1>
  WHEN <expression_2> THEN <result_2>
  ...
  ELSE                     <default_result>  -- 可选
END

搜索型 CASE 表达式

CASE
  WHEN <condition_1> THEN <result_1>
  WHEN <condition_2> THEN <result_2>
  ...
  ELSE                    <default_result>  -- 可选
END
  • 简单 CASE:仅适用于一列,使用 = 比较。
  • 搜索型 CASE:可以比较任意列和表达式。

典型使用场景

1. ORDER BY 子句

将联系人按类型排序:fixed linemobileemailicq 的顺序,同时在每个组内按具体值排序。

SELECT *
FROM   contact
ORDER  BY
       CASE contact_type
         WHEN 'fixed line' THEN 0
         WHEN 'mobile'     THEN 1
         WHEN 'email'      THEN 2
         WHEN 'icq'        THEN 3
         ELSE                   4
       END,
       contact_value;

按体重分类并排序,每类内部按姓名排序:

SELECT firstname, lastname, weight,
       CASE
         WHEN (weight IS NULL OR weight = 0) THEN 'weight is unknown'
         WHEN weight < 40                    THEN 'lightweight'
         WHEN weight BETWEEN 40 AND 85       THEN 'medium'
         ELSE                                     'heavyweight'
       END
FROM   person
ORDER  BY
       CASE
         WHEN (weight IS NULL OR weight = 0) THEN 0
         WHEN weight < 40                    THEN 1
         WHEN weight BETWEEN 40 AND 85       THEN 2
         ELSE                                     3
       END, lastname, firstname;

2. WHERE 子句

将 CASE 用作过滤条件。在下面的例子中,不同出生地的人体重被动态调整:

SELECT *
FROM   person
WHERE  CASE
         WHEN place_of_birth = 'Dallas'   THEN weight * 0.8
         WHEN place_of_birth = 'Richland' THEN weight * 0.9
         ELSE                                  weight
       END > 80
OR     weight < 20;

总结

  • 简单 CASE 表达式 是列值的简单映射,用于等值比较。
  • 搜索型 CASE 表达式 提供更灵活的表达式评估,可以处理复杂逻辑。
  • CASE 可用于 SELECTORDER BYWHERE 子句中,是强大的 SQL 工具。
最后修改: 2025年01月28日 星期二 13:08