2024年9月26日: PostgreSQL 17 发布!
支持的版本:当前 (17) / 16 / 15 / 14 / 13 / 12
开发版本:devel
不受支持的版本: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
...

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

9.25.2. NOT IN #

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

右侧是一个带括号的表达式列表。如果左侧表达式的结果不等于右侧的所有表达式,则结果为。这是一种简写形式,用于

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

请注意,如果左侧表达式产生空值,或者右侧没有相等的值并且至少一个右侧表达式产生空值,则NOT IN构造的结果将为空,而不是像人们直观期望的那样为真。这符合 SQL 对空值布尔组合的常规规则。

提示

x NOT IN y 在所有情况下都等价于 NOT (x IN y)。但是,与使用IN相比,在使用NOT IN时,空值更有可能使新手犯错。如果可能,最好用肯定的方式表达你的条件。

9.25.3. ANY/SOME (数组) #

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

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

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

SOMEANY的同义词。

9.25.4. ALL (数组) #

expression operator ALL (array expression)

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

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

9.25.5. 行构造器比较 #

row_constructor operator row_constructor

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

=<>情况的工作方式略有不同。如果所有对应的成员均非空且相等,则认为两行相等;如果任何对应的成员均非空且不相等,则认为两行不相等;否则,行比较的结果未知(空)。

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

row_constructor IS DISTINCT FROM row_constructor

此构造类似于<>行比较,但它不会对空输入产生空值。相反,任何空值都被认为与任何非空值不相等(不同),并且任何两个空值都被认为相等(不不同)。因此,结果将为真或假,绝不会为空。

row_constructor IS NOT DISTINCT FROM row_constructor

此构造类似于=行比较,但它不会对空输入产生空值。相反,任何空值都被认为与任何非空值不相等(不同),并且任何两个空值都被认为相等(不不同)。因此,结果将始终为真或假,绝不会为空。

9.25.6. 复合类型比较 #

record operator record

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

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

为了支持匹配包含没有默认 B 树操作符类的元素的行,为复合类型比较定义了以下操作符:*=*<>*<*<=*>*>=。这些操作符比较两行的内部二进制表示。即使使用等号操作符比较两行结果为真,这两行也可能具有不同的二进制表示。在这些比较操作符下的行排序是确定的,但没有其他意义。这些操作符在内部用于物化视图,并且可能对其他专门用途(如复制和 B 树去重(参见第 64.1.4.3 节))有用。不过,它们并非旨在用于编写查询。

提交更正

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