本节介绍 PostgreSQL 中可用的符合 SQL 标准的条件表达式。
如果您的需求超出了这些条件表达式的功能,您可能需要考虑使用更具表现力的编程语言编写服务器端函数。
尽管 COALESCE
、GREATEST
和 LEAST
在语法上与函数类似,但它们不是普通函数,因此不能与显式 VARIADIC
数组参数一起使用。
CASE
#SQL CASE
表达式是一个通用的条件表达式,类似于其他编程语言中的 if/else 语句
CASE WHENcondition
THENresult
[WHEN ...] [ELSEresult
] END
CASE
子句可以在任何有效表达式的任何位置使用。每个 condition
都是返回 boolean
结果的表达式。如果条件的结果为 true,则 CASE
表达式的值为条件后面的 result
,并且不会处理 CASE
表达式的其余部分。如果条件的结果不为 true,则以相同的方式检查任何后续 WHEN
子句。如果没有 WHEN
condition
产生 true,则 CASE
表达式的值为 ELSE
子句的 result
。如果省略 ELSE
子句并且没有条件为 true,则结果为 null。
一个示例
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
表达式的类型都必须可以转换为单个输出类型。有关更多详细信息,请参见第 10.5 节。
有一种 CASE
表达式的““简单””形式,它是上述通用形式的变体
CASEexpression
WHENvalue
THENresult
[WHEN ...] [ELSEresult
] 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;
如 第 4.2.14 节 中所述,在各种情况下,表达式的子表达式在不同时间计算,因此““CASE
仅计算必要的子表达式””这一原则并非铁定不变。例如,一个常量 1/0
子表达式通常会在规划时导致除以零失败,即使它位于运行时永远不会进入的 CASE
分支中。
COALESCE
#COALESCE
(value
[, ...])
COALESCE
函数返回其第一个非空参数。仅当所有参数都为空时才返回空值。它通常用于在检索数据以进行显示时用默认值替换空值,例如
SELECT COALESCE(description, short_description, '(none)') ...
如果 description
不为空,则返回 description
,否则如果 short_description
不为空,则返回 short_description
,否则返回 (none)
。
所有参数都必须可以转换为公共数据类型,该数据类型将是结果的类型(有关详细信息,请参见 第 10.5 节)。
与 CASE
表达式类似,COALESCE
仅计算确定结果所需的那些参数;也就是说,不会计算第一个非空参数右侧的参数。此 SQL 标准函数提供了与 NVL
和 IFNULL
类似的功能,这些功能在其他一些数据库系统中使用。
NULLIF
#NULLIF
(value1
,value2
)
如果 value1
等于 value2
,NULLIF
函数将返回一个 null 值;否则它将返回 value1
。这可用于执行上面给出的 COALESCE
示例的逆操作
SELECT NULLIF(value, '(none)') ...
在此示例中,如果 value
为 (none)
,则返回 null,否则返回 value
的值。
两个参数必须为可比较类型。具体来说,它们之间的比较完全就像你写
一样,因此必须有一个合适的 value1
= value2
=
运算符可用。
结果与第一个参数具有相同的类型——但有一个细微差别。实际返回的是隐式 =
运算符的第一个参数,并且在某些情况下,该参数将被提升为与第二个参数的类型匹配。例如,NULLIF(1, 2.2)
产生 numeric
,因为没有 integer
=
numeric
运算符,只有 numeric
=
numeric
。