9.23. 行和数组比较

本节介绍了几种用于在值组之间进行多个比较的特殊构造。这些形式在语法上与上一节的子查询形式有关,但不涉及子查询。涉及数组子表达式的形式是 PostgreSQL 扩展。其余的都符合 SQL。本节中记录的所有表达式形式均返回布尔(真/假)结果。

9.23.1. IN

expression IN (value [, ...])

右侧是带括号的标量表达式列表。如果左侧表达式的结果等于任何右侧表达式,则结果为“ true”。这是的简写

expression = value1
OR
expression = value2
OR
...

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

9 .23.2. 不在

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

右侧是带括号的标量表达式列表。如果左侧表达式的结果与所有右侧表达式都不相等,则结果为“ true”。这是的简写

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

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

Tip

在所有情况下,x NOT IN y等于NOT (x IN y)。但是,与IN一起使用时,与IN一起使用时,空值使新手崩溃的可能性更大。如果可能的话,最好是积极地表达自己的状况。

9 .23.3. ANY/SOME(数组)

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

右侧是带括号的表达式,必须产生一个数组值。使用给定的* operator *评估左侧表达式并将其与数组的每个元素进行比较,该表达式必须产生布尔结果。如果获得任何真结果,则ANY的结果为“真”。如果找不到正确的结果(包括数组具有零个元素的情况),则结果为“ false”。

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

SOMEANY的同义词。

9 .23.4. 全部(数组)

expression operator ALL (array expression)

右侧是带括号的表达式,必须产生一个数组值。使用给定的* operator *评估左侧表达式并将其与数组的每个元素进行比较,该表达式必须产生布尔结果。如果所有比较都得出 true(包括数组具有零个元素的情况),则ALL的结果为“ true”。如果发现任何错误结果,则结果为“ false”。

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

9 .23.5. 行构造器比较

row_constructor operator row_constructor

每一侧都是一个行构造器,如Section 4.2.13中所述。两个行值必须具有相同数量的字段。对每一侧进行评估,然后逐行进行比较。当* operator *为=<><<=>>=时,允许进行行构造器比较。每个行元素必须是具有默认 B 树操作符类的类型,否则尝试进行比较可能会产生错误。

Note

如果使用较早的列解决了比较,则可能不会发生与元素的数量或类型有关的错误。

=<>案例与其他案例略有不同。如果两行的所有对应成员均为非 null 且相等,则认为两行相等;如果任何相应的成员为非空且不相等,则行不相等;否则,行比较的结果未知(空)。

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

Note

在 PostgreSQL 8.2 之前,按照 SQL 规范未处理<<=>>=情况。像ROW(a,b) < ROW(c,d)这样的比较被实现为a < c AND b < d,而正确的行为等效于a < c OR (a = c AND b < d)

row_constructor IS DISTINCT FROM row_constructor

此构造类似于<>行比较,但对于空 Importing 不会产生空值。取而代之的是,任何空值都被认为与任何非空值不相等(相异),并且任何两个空值都被视为相等(不相异)。因此结果将为 true 或 false,从不为 null。

row_constructor IS NOT DISTINCT FROM row_constructor

此构造类似于=行比较,但对于空 Importing 不会产生空值。取而代之的是,任何空值都被认为与任何非空值不相等(相异),并且任何两个空值都被视为相等(不相异)。因此,结果将始终为 true 或 false,从不为 null。

9 .23.6. 复合类型比较

record operator record

如果结果依赖于比较两个 NULL 值或 NULL 和非 NULL,则 SQL 规范要求按行比较以返回 NULL。 PostgreSQL 仅在比较两个行构造函数的结果(如Section 9.23.5)或将行构造函数与子查询的输出(如Section 9.22)进行比较时才这样做。在比较两个复合类型值的其他上下文中,两个 NULL 字段值被视为相等,并且 NULL 被认为大于非 NULL。为了使复合类型具有一致的排序和索引行为,这是必需的。

对每一侧进行评估,然后逐行进行比较。当* operator *为=<><<=>>=或具有与其中之一相似的语义时,允许进行复合类型比较。 (具体来说,如果运算符是 B 树运算符类的成员,或者是 B 树运算符类的=成员的否定符,则它可以是行比较运算符.)上述运算符的默认行为与行构造器的IS [ NOT ] DISTINCT FROM相同(请参见Section 9.23.5)。

为了支持包含没有默认 B-tree 运算符类的元素的行的匹配,为复合类型比较定义了以下运算符:*=*<>*<*<=*>*>=。这些运算符比较两行的内部二进制表示形式。即使两行与相等运算符的比较为真,两行也可能具有不同的二进制表示形式。这些比较运算符下的行 Sequences 是确定性的,但没有其他意义。这些运算符在内部用于物化视图,并且可能对其他特殊目的(例如复制)有用,但通常不适用于编写查询。