Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16

9.24 行和数组比较 #

9.24.1. IN
9.24.2. NOT IN
9.24.3. ANY/SOME(数组)
9.24.4. ALL(数组)
9.24.5. 行构造函数比较
9.24.6. 复合类型比较

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

9.24.1. IN #

expression IN (value [, ...])

右侧是一个带括号的表达式列表。如果左侧表达式的结果等于任何右侧表达式,则结果为 true。这是以下内容的简写符号

expression = value1
OR
expression = value2
OR
...

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

9.24.2. NOT IN #

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

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

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

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

提示

x NOT IN y 在所有情况下都等效于 NOT (x IN y)。但是,在使用 NOT IN 时,null 值比在使用 IN 时更容易让新手绊倒。如果可能,最好以肯定的方式表达你的条件。

9.24.3. ANY/SOME(数组) #

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

右侧是一个带括号的表达式,它必须产生一个数组值。对左侧表达式求值,并使用给定的 operator 将其与数组的每个元素进行比较,该运算符必须产生一个布尔结果。如果获得任何 true 结果,则 ANY 的结果为 true。如果没有找到 true 结果(包括数组元素为零的情况),则结果为 false

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

SOMEANY 的同义词。

9.24.4. ALL(数组)#

expression operator ALL (array expression)

右侧是一个括号表达式,它必须产生一个数组值。对左侧表达式进行求值,并使用给定的 operator(它必须产生一个布尔结果)将其与数组的每个元素进行比较。如果所有比较都产生真(包括数组没有元素的情况),则 ALL 的结果为 true。如果找到任何错误结果,则结果为 false

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

9.24.5. 行构造器比较 #

row_constructor operator row_constructor

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

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

对于 <<=>>= 情况,行元素从左到右进行比较,一旦找到不匹配或空元素对便停止。如果该元素对中的任一元素为空,则行比较结果未知(空);否则,该元素对的比较决定结果。例如,ROW(1,2,NULL) < ROW(1,3,0) 的结果为真,而非空,因为第三对元素未被考虑。

row_constructor IS DISTINCT FROM row_constructor

此构造类似于 <> 行比较,但它不会为 null 输入生成 null。相反,任何 null 值都被视为不等于(不同于)任何非 null 值,任何两个 null 都被视为相等(不不同)。因此,结果将始终为真或假,绝不会为 null。

row_constructor IS NOT DISTINCT FROM row_constructor

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

9.24.6. 复合类型比较 #

record operator record

SQL 规范要求行比较在结果取决于比较两个 NULL 值或一个 NULL 值和一个非 NULL 值时返回 NULL。PostgreSQL 仅在比较两个行构造函数的结果(如 第 9.24.5 节 所述)或将行构造函数与子查询的输出进行比较(如 第 9.23 节 所述)时才执行此操作。在比较两个复合类型值的其他情况下,两个 NULL 字段值被视为相等,而 NULL 被视为大于非 NULL。为了对复合类型具有持续的排序和索引行为,这是必需的。

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

为了支持匹配包括不带默认 B 树操作符类的元素的行,针对复合类型比较定义了以下操作符:*=*<>*<*<=*>*>=。这些操作符比较两行的内部二进制表示形式。即使使用相等操作符比较两行时为真,两行也可能具有不同的二进制表示形式。这些比较操作符下的行排序是确定性的,但没有其他含义。这些操作符在内部用于物化视图,并且可能对其他专门用途(例如复制和 B 树重复数据删除(请参阅第 67.4.3 节))有用。不过,它们并不旨在普遍用于编写查询。