↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4
历史版本。 PostgreSQL 12 已结束支持。 2024-11-21. 请参阅 当前版本手册.

9.23. 行和数组比较 #

本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。涉及数组子表达式的形式是 PostgreSQL 的扩展;其余形式是 SQL 兼容的。本节介绍的所有表达式形式都返回布尔(Boolean)结果(真/假)。

9.23.1. IN #

expression IN (value [, ...])

右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果等于右侧任一表达式的结果,则结果为“真”。这等价于以下写法:

expression = value1
OR
expression = value2
OR
...

请注意如果左手边表达式得到空值,或者没有相等的右手边值并且至少有一个右手边的表达式得到空值,那么 IN 结构的结果将为空值,而不是假。这符合 SQL 处理空值的布尔组合的一般规则。

9.23.2. NOT IN

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

右侧是一个用圆括号括起来的表达式列表。如果左侧表达式的结果与右侧所有表达式的结果都不相等,则结果为“真”。这等价于以下写法:

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

请注意如果左手边表达式得到空值,或者没有相等的右手边值并且至少有一个右手边的表达式得到空值,那么 NOT IN 结构的结果将为空值,而不是我们可能天真地认为的真值。这符合 SQL 处理空值的布尔组合的一般规则。

提示

x NOT IN y 在所有情况下都等效于 NOT (x IN y)。但是,在处理空值的时候,用 NOT IN 比用 IN 更可能迷惑新手。最好尽可能用正逻辑来表达你的条件。

9.23.3. ANY/SOME(数组)

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

右侧是一个用括号括起来的表达式,它必须产生一个数组值。左侧表达式会被求值,并使用给定的 operator 与数组的每个元素进行比较,该操作符必须产生布尔结果。如果得到了任何真值结果,那么 ANY 的结果是“真”。如果没有找到真值结果(包括数组有零个元素的情况),那么结果是“假”。

如果数组表达式得到的是 null 数组,那么 ANY 的结果将为 null。如果左手边的表达式得到 null,ANY 通常也为 null(尽管非严格比较操作符可能得到不同结果)。另外,如果右手边数组包含任何 null 元素,并且没有得到真值比较结果,那么 ANY 的结果将为 null 而不是假(同样假设这里使用的是严格比较操作符)。这符合 SQL 处理 null 值布尔组合的一般规则。

SOME 是 ANY 的同义词。

9.23.4. ALL(数组)

expression operator ALL (array expression)

右侧是一个用括号括起来的表达式,它必须产生一个数组值。左侧表达式会被求值,并使用给定的 operator 与数组的每个元素进行比较,该操作符必须产生布尔结果。如果所有比较都得到真值结果,那么 ALL 的结果是“真”(包括数组有零个元素的情况)。如果有任何假值结果,那么结果是“假”。

如果数组表达式得到的是 null 数组,那么 ALL 的结果将为 null。如果左手边的表达式得到 null,ALL 通常也为 null(尽管非严格比较操作符可能得到不同结果)。另外,如果右手边数组包含任何 null 元素,并且没有得到假值比较结果,那么 ALL 的结果将为 null 而不是真(同样假设这里使用的是严格比较操作符)。这符合 SQL 处理 null 值布尔组合的一般规则。

9.23.5. 行构造器比较 #

row_constructor operator row_constructor

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

=和<> 情况略有不同。如果两行的所有对应成员都是非空且相等则这两行被认为相等;如果任何对应成员是非空但是不相等则这两行不相等;否则行比较的结果为未知(空值)。

对于<、<=、> 和>=这几种情况,会从左到右比较各行元素,一旦找到一对不相等或含有 null 的元素就立即停止。如果这对元素中的任意一个为 null,那么行比较的结果就是未知(null);否则,这对元素的比较结果决定整个行比较的结果。例如,ROW(1,2,NULL) < ROW(1,3,0) 的结果为真,而不是 null,因为第三对元素并不会被考虑。

注意

在 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

这个结构与<> 行比较相似,但是它对于空值输入不会得到空值。任何空值被认为和任何非空值不相等(有区别),并且任意两个空值被认为相等(无区别)。因此结果将总是为真或为假,永远不会是空值。

row_constructor IS NOT DISTINCT FROM row_constructor

这个结构与=行比较相似,但是它对于空值输入不会得到空值。任何空值被认为和任何非空值不相等(有区别),并且任意两个空值被认为相等(无区别)。因此结果将总是为真或为假,永远不会是空值。

9.23.6. 复合类型比较 #

record operator record

SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时行比较返回 NULL。PostgreSQL 只有在比较两个行构造器(如第 9.23.5 节)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如第 9.22 节中所述)。在其他比较两个复合类型值的环境中,两个 NULL 字段值被认为相等,并且一个 NULL 被认为大于一个非 NULL。为了得到复合类型的一致的排序和索引行为,这样做是必要的。

对两侧分别求值后,按行进行比较。当 operator 是 =、<>、<、<=、> 或者 >=时或者具有与这些类似的语义时,允许复合类型的比较(更准确地说,如果一个操作符是一个 B-树操作符类的成员,或者是一个 B-树操作符类的=成员的否定操作符,它就可以是一个行比较操作符)。上述操作符的默认行为与用于行构造器(见第 9.23.5 节)的 IS [ NOT ] DISTINCT FROM 相同。

为了支持包含无默认 B-树操作符类的元素的行匹配,为复合类型比较定义了下列操作符:*=、*<>、*<、*<=、*> 以及 *>=。这些操作符比较两行的内部二进制表示。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表示。使用这些比较操作符得到的行排序是确定的,但除此之外没有其他意义。这些操作符在内部被用于物化视图并且可能对其他如复制之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.