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

9.25. 行和数组比较 #

9.25.1. IN
9.25.2. NOT IN
9.25.3. ANY/SOME(数组)
9.25.4. ALL(数组)
9.25.5. 行构造函数比较
9.25.6. 复合类型比较

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

9.25.1. IN #

expression IN (value [, ...])

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

expression = value1
OR
expression = value2
OR
...

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

9.25.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)。但是,与处理 IN 相比,null 值很可能会在处理 NOT IN 时使新手感到困惑。如果可能,最好以积极的方式表达你的条件。

9.25.3. ANY/SOME(数组)#

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

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

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

SOMEANY 的同义词。

9.25.4. ALL(array)#

expression operator ALL (array expression)

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

如果数组表达式产生一个 null 数组,ALL 的结果将为 null。如果左侧表达式的值为 null,ALL 的结果通常是 null(虽然非严格的比较运算符可能会产生不同的结果)。此外,如果右侧数组包含任何 null 元素,并且没有得到任何为假的比较结果,ALL 的结果将是 null,而不是 true(再次假设是一个严格比较运算符)。这与 SQL 中 null 值的布尔组合的一般规则是一致的。

9.25.5. 行构造函数比较 #

row_constructor operator row_constructor

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

=<>情况的工作方式与其他情况略有不同。如果所有相应成员均为非空且相等,则两行被视为相等;如果任何相应成员为非空且不相等,则这些行不相等;否则行比较结果未知 (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.25.6. 复合类型比较 #

record operator record

SQL 规范要求行比较返回 NULL 是结果取决于比较两个 NULL 值或比较 NULL 和非 NULL 值。PostgreSQL 仅在比较两个行构造函数的结果(如 第 9.25.5 节)或将行构造函数与子查询的输出进行比较(如 第 9.24 节)时执行此操作。在比较两个复合类型值的其他上下文中,将两个 NULL 字段值视为相等,而将 NULL 视为比非 NULL 大。为了使复合类型的排序和索引行为保持一致,这样做是必要的。

对每一行进行求值,并行比较。在 运算符=<><<=>>=,或者具有与其中一个运算符类似的语义时,允许进行复合类型比较。(具体来说,如果运算符是 B 树运算符类的成员,或者是不等于 B-树运算符类中 = 成员的否定运算符,则该操作符可以是行比较运算符。)以上运算符的默认行为与行构造函数的 IS [ NOT ] DISTINCT FROM 相同(请参阅 第 9.25.5 节)。

为了支持包括没有默认 B 树运算符类的元素的行匹配,为复合类型比较定义了以下运算符:*=*<>*<*<=*>*>=。这些运算符比较两行的内部二进制表示形式。即使使用等式运算符比较两行时为真,这两行也可能有不同的二进制表示形式。在这些比较运算符下,行的排序具有确定性,但没有其他意义。这些运算符在内联视图中供内部使用,可能对其他特殊用途(例如复制和 B 树重复数据删除,请参阅 第 64.1.4.3 节)有用。不过,它们并非旨在作为编写查询时使用。