本节介绍了用于在值组之间进行多重比较的几种专门结构。这些形式在语法上与上一节的子查询形式相关,但并不涉及子查询。涉及数组子表达式的形式是 PostgreSQL 扩展;其余形式符合 SQL。本节中记录的所有表达式形式都返回布尔值(真/假)结果。
IN
#expression
IN (value
[, ...])
右侧是一个带括号的表达式列表。如果左侧表达式的结果等于任何右侧表达式,则结果为 “true”。这是以下内容的简写符号
expression
=value1
ORexpression
=value2
OR ...
请注意,如果左侧表达式产生 null,或者如果没有相等的右侧值且至少有一个右侧表达式产生 null,则 IN
结构的结果将为 null,而不是 false。这符合 SQL 对 null 值的布尔组合的常规规则。
NOT IN
#expression
NOT IN (value
[, ...])
右侧是一个带括号的表达式列表。如果左侧表达式的结果不等于所有右侧表达式,则结果为 “true”。这是以下内容的简写符号
expression
<>value1
ANDexpression
<>value2
AND ...
请注意,如果左侧表达式产生 null,或者如果没有相等的右侧值且至少有一个右侧表达式产生 null,则 NOT IN
结构的结果将为 null,而不是人们可能天真地期望的 true。这符合 SQL 对 null 值的布尔组合的常规规则。
x NOT IN y
在所有情况下都等效于 NOT (x IN y)
。但是,在使用 NOT IN
时,null 值比在使用 IN
时更容易让新手绊倒。如果可能,最好以肯定的方式表达你的条件。
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 值的布尔组合的常规规则。
SOME
是 ANY
的同义词。
ALL
(数组)#expression
operator
ALL (array expression
)
右侧是一个括号表达式,它必须产生一个数组值。对左侧表达式进行求值,并使用给定的 operator
(它必须产生一个布尔结果)将其与数组的每个元素进行比较。如果所有比较都产生真(包括数组没有元素的情况),则 ALL
的结果为 “true”。如果找到任何错误结果,则结果为 “false”。
如果数组表达式产生一个空数组,则 ALL
的结果将为空。如果左侧表达式产生空,则 ALL
的结果通常为空(尽管非严格比较运算符可能会产生不同的结果)。此外,如果右侧数组包含任何空元素并且没有获得错误的比较结果,则 ALL
的结果将为空,而不是真(再次假设一个严格的比较运算符)。这符合 SQL 关于空值的布尔组合的正常规则。
row_constructor
operator
row_constructor
每一侧都是一个行构造器,如 第 4.2.13 节 所述。两个行构造器必须具有相同数量的字段。给定的 operator
应用于每对对应的字段。(由于字段的类型可能不同,这意味着可以为每对选择不同的特定运算符。)所有选定的运算符必须是某个 B 树运算符类的成员,或者是一个 B 树运算符类的 =
成员的否定,这意味着只有当 operator
是 =
、<>
、<
、<=
、>
或 >=
,或具有与其中一个类似的语义时,行构造器比较才有可能。
=
和 <>
情况与其他情况的工作方式略有不同。如果所有对应的成员都为非空且相等,则两行被认为相等;如果任何对应的成员为非空且不相等,则这两行不相等;否则,行比较的结果未知(空)。
对于 <
、<=
、>
和 >=
情况,行元素从左到右进行比较,一旦找到不匹配或空元素对便停止。如果该元素对中的任一元素为空,则行比较结果未知(空);否则,该元素对的比较决定结果。例如,ROW(1,2,NULL) < ROW(1,3,0)
的结果为真,而非空,因为第三对元素未被考虑。
row_constructor
IS DISTINCT FROMrow_constructor
此构造类似于 <>
行比较,但它不会为 null 输入生成 null。相反,任何 null 值都被视为不等于(不同于)任何非 null 值,任何两个 null 都被视为相等(不不同)。因此,结果将始终为真或假,绝不会为 null。
row_constructor
IS NOT DISTINCT FROMrow_constructor
此构造类似于 =
行比较,但它不会为 null 输入生成 null。相反,任何 null 值都被视为不等于(不同于)任何非 null 值,任何两个 null 都被视为相等(不不同)。因此,结果将始终为真或假,绝不会为 null。
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 节))有用。不过,它们并不旨在普遍用于编写查询。