2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不再支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4

9.25. 行和数组比较 #

本节描述了几种用于对值组进行多重比较的专用构造。这些形式在语法上与上一节的子查询形式相关,但不涉及子查询。涉及数组子表达式的形式是PostgreSQL的扩展;其余形式符合SQL-标准。本节记录的所有表达式形式都返回布尔(真/假)结果。

9.25.1. IN #

expression IN (value [, ...])

右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果等于右侧任何一个表达式,则结果为。这是以下内容的简写表示:

expression = value1
OR
expression = value2
OR
...

请注意,如果左侧表达式产生 NULL,或者没有相等的右侧值且至少一个右侧表达式产生 NULL,则 IN 构造的结果将是 NULL,而不是 FALSE。这符合 SQL 对 NULL 值布尔组合的正常规则。

9.25.2. NOT IN #

expression NOT IN (value [, ...])

右侧是一个用括号括起来的表达式列表。如果左侧表达式的结果不等于右侧所有表达式,则结果为。这是以下内容的简写表示:

expression <> value1
AND
expression <> value2
AND
...

请注意,如果左侧表达式产生 NULL,或者没有相等的右侧值且至少一个右侧表达式产生 NULL,则 NOT IN 构造的结果将是 NULL,而不是像人们可能 naively 预期的那样是 TRUE。这符合 SQL 对 NULL 值布尔组合的正常规则。

提示

x NOT IN y 在所有情况下都等同于 NOT (x IN y)。然而,在处理 NOT IN 时,NULL 值比处理 IN 时更容易使新手感到困惑。如果可能,最好以积极的方式表达您的条件。

9.25.3. ANY/SOME (数组) #

expression operator ANY (array expression)
expression operator SOME (array expression)

右侧是一个用括号括起来的表达式,它必须产生一个数组值。左侧表达式被计算,并使用给定的operator与数组中的每个元素进行比较,该operator必须产生一个布尔结果。如果得到任何真结果,则 ANY 的结果为。如果未找到真结果(包括数组为空的情况),则结果为

如果数组表达式产生一个 NULL 数组,则 ANY 的结果将是 NULL。如果左侧表达式产生 NULL,则 ANY 的结果通常是 NULL(尽管非严格的比较运算符可能产生不同的结果)。此外,如果右侧数组包含任何 NULL 元素且未获得真比较结果,则 ANY 的结果将是 NULL,而不是 FALSE(同样,假设使用严格的比较运算符)。这符合 SQL 对 NULL 值布尔组合的正常规则。

SOMEANY 的同义词。

9.25.4. ALL (数组) #

expression operator ALL (array expression)

右侧是一个用括号括起来的表达式,它必须产生一个数组值。左侧表达式被计算,并使用给定的operator与数组中的每个元素进行比较,该operator必须产生一个布尔结果。如果所有比较都产生真(包括数组为空的情况),则 ALL 的结果为。如果找到任何假结果,则结果为

如果数组表达式产生一个 NULL 数组,则 ALL 的结果将是 NULL。如果左侧表达式产生 NULL,则 ALL 的结果通常是 NULL(尽管非严格的比较运算符可能产生不同的结果)。此外,如果右侧数组包含任何 NULL 元素且未获得假比较结果,则 ALL 的结果将是 NULL,而不是 TRUE(同样,假设使用严格的比较运算符)。这符合 SQL 对 NULL 值布尔组合的正常规则。

9.25.5. 行构造器比较 #

row_constructor operator row_constructor

每一侧都是一个行构造器,如第 4.2.13 节中所述。两个行构造器必须具有相同数量的字段。给定的operator应用于每一对对应的字段。(由于字段可能是不同类型,这意味着每对字段可能会选择不同的具体运算符。)所有选定的运算符都必须属于某个 B-tree 运算符类,或者是一个 B-tree 运算符类中 = 运算符的否定运算符,这意味着行构造器比较仅在operator=, <>, <, <=, >, 或 >=,或者其语义与其中之一类似时才可能。)

=<> 的情况与其他情况略有不同。如果两个行的所有对应成员都非 NULL 且相等,则认为这两个行相等;如果任何对应成员非 NULL 且不相等,则认为这两个行不相等;否则,行比较的结果为未知(NULL)。

对于 <, <=, >>= 的情况,行元素从左到右进行比较,一旦找到不相等或 NULL 的元素对就停止。如果这对元素中的任何一个为 NULL,则行比较的结果为未知(NULL);否则,该对元素的比较将决定结果。例如,ROW(1,2,NULL) < ROW(1,3,0) 返回 TRUE,而不是 NULL,因为第三对元素未被考虑。

row_constructor IS DISTINCT FROM row_constructor

此构造类似于 <> 行比较,但它不会为 NULL 输入返回 NULL。相反,任何 NULL 值都被认为与任何非 NULL 值不相等(不同),并且任何两个 NULL 值都被认为相等(不不同)。因此,结果要么为 TRUE,要么为 FALSE,绝不会是 NULL。

row_constructor IS NOT DISTINCT FROM row_constructor

此构造类似于 = 行比较,但它不会为 NULL 输入返回 NULL。相反,任何 NULL 值都被认为与任何非 NULL 值不相等(不同),并且任何两个 NULL 值都被认为相等(不不同)。因此,结果将始终为 TRUE 或 FALSE,绝不会是 NULL。

9.25.6. 复合类型比较 #

record operator record

SQL 标准要求行比较在比较两个 NULL 值或一个 NULL 和一个非 NULL 值时返回 NULL。 PostgreSQL 仅在比较两个行构造器的结果(如第 9.25.5 节)或将行构造器与子查询的输出进行比较(如第 9.24 节)时执行此操作。在其他比较两个复合类型值的上下文中,两个 NULL 字段值被认为相等,而 NULL 被认为大于非 NULL。这对于复合类型具有一致的排序和索引行为是必需的。

每一侧都被计算并逐行进行比较。当operator=, <>, <, <=, >>=,或者其语义与其中之一类似时,允许复合类型比较。(具体来说,如果一个运算符是一个 B-tree 运算符类的成员,或者是一个 B-tree 运算符类中 = 成员的否定运算符,那么它就可以是一个行比较运算符。)上述运算符的默认行为与行构造器的 IS [ NOT ] DISTINCT FROM 相同(参见第 9.25.5 节)。

为了支持包含没有默认 B-tree 运算符类的元素的行的匹配,为复合类型比较定义了以下运算符:*=, *<>, *<, *<=, *>, 和 *>=。这些运算符比较行的内部二进制表示。即使使用相等运算符比较两个行返回 TRUE,两个行也可能具有不同的二进制表示。这些比较运算符下的行顺序是确定的,但否则无意义。这些运算符在内部用于物化视图,并且可能用于其他专用目的,例如复制和 B-Tree 去重(参见第 65.1.4.3 节)。但它们并不打算普遍用于编写查询。

提交更正

如果您在文档中发现任何不正确、不符合您对特定功能的使用体验或需要进一步澄清的内容,请使用此表单报告文档问题。