Postgresql 中文操作指南

9.24. Row and Array Comparisons #

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

9.24.1. IN #

expression IN (value [, ...])

右侧是一个括号中的表达式列表。如果左侧表达式的结果等于任何右侧表达式,则结果为“真”。这是下列表达式的简写:

expression = value1
OR
expression = value2
OR
...

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

9.24.2. NOT IN #

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

右侧是一个括号中的表达式列表。如果左侧表达式的结果不等于所有右侧表达式,则结果为“真”。这是下列表达式的简写:

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

请注意,如果左侧表达式产生 Null,或者没有相等的右侧值且至少有一个右侧表达式产生 Null,则 NOT IN 结构的结果将为 Null,而不是直觉上预期的真。这符合 SQL 的 Null 值布尔组合的常规规则。

Tip

在所有情况下,x NOT IN y 等同于 NOT (x IN y)。但是,与 IN 相比,Null 值在 NOT IN 中绊倒新手的可能性更大。如果可能,最好以肯定的形式表达条件。

9.24.3. ANY/SOME (array) #

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

右侧是一个括号中的表达式,它必须产生一个数组值。左侧表达式将得到评估,并根据指定的 operator 与数组的每个元素进行比较,operator 必须产生一个 Boolean 结果。如果得到任何真结果,则 ANY 的结果为“真”。如果未找到任何真结果(包括数组中元素为零的情况),则结果为“假”。

如果数组表达式产生一个 Null 数组,则 ANY 的结果将为 Null。如果左侧表达式产生 Null,则 ANY 的结果通常为 Null(虽然非严格比较运算符可能会产生不同的结果)。此外,如果右侧数组包含任何 Null 元素,并且未得到任何真比较结果,则 ANY 的结果将为 Null,而不是假(同样,假定是一个严格比较运算符)。这符合 SQL 的 Null 值布尔组合的常规规则。

SOMEANY 的同义词。

9.24.4. ALL (array) #

expression operator ALL (array expression)

右侧是一个括号中的表达式,它必须产生一个数组值。左侧表达式将得到评估,并根据指定的 operator 与数组的每个元素进行比较,operator 必须产生一个 Boolean 结果。如果所有比较都产生真(包括数组中元素为零的情况),则 ALL 的结果为“真”。如果找到任何假结果,则结果为“假”。

如果数组表达式产生一个 Null 数组,则 ALL 的结果将为 Null。如果左侧表达式产生 Null,则 ALL 的结果通常为 Null(虽然非严格比较运算符可能会产生不同的结果)。此外,如果右侧数组包含任何 Null 元素,并且未得到任何假比较结果,则 ALL 的结果将为 Null,而不是真(同样,假定是一个严格比较运算符)。这符合 SQL 的 Null 值布尔组合的常规规则。

9.24.5. Row Constructor Comparison #

row_constructor operator row_constructor

每一方都是行构造函数,如 Section 4.2.13 中所述。两个行构造函数必须具有相同数量的字段。给定的 operator 应用于每对相应字段。(由于字段可以是不同类型,这意味着可以针对每对字段选择不同的特定运算符。)所有选定的运算符都必须是一些 B 树运算符类中的成员,或成为 B 树运算符类中一个 = 成员的否定者,这意味着行构造函数比较仅在 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.24.6. Composite Type Comparison #

record operator record

SQL 规范要求按行比较返回 NULL(如果结果依赖于比较两个 NULL 值或者 NULL 和非 NULL)。PostgreSQL 仅在比较两个行构造函数的结果(如 Section 9.24.5 中)或将行构造函数与子查询的输出进行比较时(如 Section 9.23 中)才会执行此操作。在其他比较两个复合类型值的环境中,两个 NULL 字段值被视为相等,NULL 被视为大于非 NULL。这样做对于复合类型的持续排序和索引行为是必需的。

对每一方进行评估,并按行进行比较。当 operator=<><>>=,或具有类似于其中一个的语义时,允许进行复合类型比较。(具体来说,如果运算符是 B 树运算符类中的成员,或者是一个 B 树运算符类中 = 成员的否定者,则可以是一个行的比较运算符。)上述运算符的默认行为与行构造函数的 IS [ NOT ] DISTINCT FROM 相同(请参阅 Section 9.24.5)。

为了支持匹配不具有默认 B 树运算符类的元素的行,定义了下列运算符用于复合类型比较:*=*<>*<*⇐*>*>=。这些运算符比较两行的内部二进制表示。即使两行的比较与等式运算符为 true,两行也可能具有不同的二进制表示。这些比较运算符下的行的排序是确定的,但没有任何其他意义。这些运算符在内嵌视图中用于内部操作,并且可能对其他专门目的有用,例如复制和 B 树重复数据删除(请参阅 Section 67.4.3)。不过,它们并不打算一般用于编写查询。