PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

9.18. 条件表达式 #

9.18.1. CASE
9.18.2. COALESCE
9.18.3. NULLIF
9.18.4. GREATEST 和 LEAST

本节介绍符合标准 SQL 规范的条件分支表达式, available in PostgreSQL.

Tip

如果你的需求超出了这些条件表达式的能力, 你可能想考虑用一种表达力更强的编程语言编写一个服务器侧函数。

Note

虽然 COALESCE、 GREATEST 和 LEAST 在语法上与函数相似, 但它们不是普通的函数, 因此不能与显式的 VARIADIC 数组参数一起使用。

9.18.1. CASE #

SQL 的 CASE 表达式是一种通用的条件表达式, 类似于其他编程语言中的 if/else 语句:

CASE WHEN condition THEN result
     [WHEN ...]
     [ELSE result]
END

CASE 子句可以用在任何表达式有效的地方。 每一个 condition 都是返回 boolean 结果的表达式。 如果条件的结果为真, 那么 CASE 表达式的值就是跟在条件之后的 result, 并且 CASE 表达式的其余部分不会被处理。 如果条件的结果不为真, 则任何后续的 WHEN 子句都会以相同的方式被考察。 如果没有任何 WHEN condition 为真, 那么 CASE 表达式的值就是 ELSE 子句的 result。 如果省略了 ELSE 子句并且没有条件为真, 结果为空。

An example:

SELECT * FROM test;

 a
---
 1
 2
 3


SELECT a,
       CASE WHEN a=1 THEN 'one'
            WHEN a=2 THEN 'two'
            ELSE 'other'
       END
    FROM test;

 a | case
---+-------
 1 | one
 2 | two
 3 | other

所有 result 表达式的数据类型都必须可转换为单一的输出类型。 更多细节请参见 Section 10.5。

CASE 表达式有一种 “简单的”形式, 它是上述一般形式的变体:

CASE expression
    WHEN value THEN result
    [WHEN ...]
    [ELSE result]
END

先计算第一个 expression, 然后把它与 WHEN 子句中的每个 value 表达式进行比较, 直到找到一个与它相等的为止。 如果没有找到匹配, 则返回 ELSE 子句的 result (或一个空值)。 这类似于 C 中的 switch 语句。

上面的例子可以用简单的 CASE 语法改写为:

SELECT a,
       CASE a WHEN 1 THEN 'one'
              WHEN 2 THEN 'two'
              ELSE 'other'
       END
    FROM test;

 a | case
---+-------
 1 | one
 2 | two
 3 | other

一个 CASE 表达式不会求值任何对确定结果没有必要的子表达式。 例如, 这是避免除以零失败的一种可能方式:

SELECT ... WHERE CASE WHEN x <> 0 THEN y/x > 1.5 ELSE false END;

Note

如 Section 4.2.14 中所述, 在各种情况下, 表达式的子表达式会在不同的时刻被求值, 因此 “CASE 只求值必要的子表达式” 这一原则并非铁律。 例如,一个常量 1/0 子表达式通常会在计划时导致除以零失败, 即便它位于一条运行时永远不会进入的 CASE 分支内。

9.18.2. COALESCE #

COALESCE(value [, ...])

COALESCE 函数返回它的参数中第一个非空的。 只有当所有参数都为空时才返回空。 它常被用来在为显示而检索数据时, 用一个默认值替换空值, 例如:

SELECT COALESCE(description, short_description, '(none)') ...

如果 description 不为空则返回它, 否则如果 short_description 不为空则返回它, 否则返回 (none)。

参数必须全都可以转换为一种公共数据类型, 它将是结果的类型 (细节请参见 Section 10.5)。

与 CASE 表达式一样, COALESCE 只对确定结果所必需的参数求值; 也就是说, 位于第一个非空参数右侧的参数不会被求值。 这个符合 SQL 标准的函数提供的功能类似于某些其他数据库系统中使用的 NVL 和 IFNULL。

9.18.3. NULLIF #

NULLIF(value1, value2)

如果 value1 等于 value2, 则 NULLIF 函数返回一个空值; 否则它返回 value1。 这可以用来执行上面给出的 COALESCE 例子的逆操作:

SELECT NULLIF(value, '(none)') ...

在这个例子中, 如果 value 是 (none), 则返回空, 否则返回 value 的值。

这两个参数必须属于可比较的类型。 具体来说, 它们的比较方式与你写了 value1 = value2 时完全相同, 因此必须有一个合适的 = 操作符可用。

结果与第一个参数具有相同的类型 — 但其中有一个细节。 实际返回的是隐含的 = 操作符的第一个参数, 而在某些情况下它已经被提升为与第二个参数的类型相匹配。 例如, NULLIF(1, 2.2) 产生 numeric, 因为不存在 integer = numeric 操作符, 只有 numeric = numeric。

9.18.4. GREATEST 和 LEAST #

GREATEST(value [, ...])
LEAST(value [, ...])

GREATEST 和 LEAST 函数从任意数量的表达式列表中选择最大或最小的值。 这些表达式必须全都可以转换为一种公共数据类型, 它将是结果的类型 (细节请参见 Section 10.5)。

参数列表中的 NULL 值会被忽略。 只有当所有表达式都求值为 NULL 时结果才会是 NULL。 (这是对 SQL 标准的一个偏离。 按照标准, 如果任何参数为 NULL, 返回值就是 NULL。 某些其他数据库的行为就是那样。)