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

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 / 7.3 / 7.2
历史版本。 PostgreSQL 7.3 已结束支持。 请参阅 当前版本手册.

6.15. 子查询表达式 #

本节描述 PostgreSQL 中可用的 SQL 兼容的子查询表达式。本节中记录的所有表达式形式都返回布尔值(真/假)结果。

6.15.1. EXISTS

EXISTS ( subquery )

EXISTS的参数是一个任意的SELECT语句,或者说子查询。系统对子查询进行运算以判断它是否返回行。如果它至少返回一行,那么EXISTS的结果就为“真”;如果子查询没有返回行,那么EXISTS的结果是“假”。

子查询可以引用外层查询的变量,这些变量在该子查询的任何一次计算中都起常量的作用。

这个子查询通常只是运行到能判断它是否可以返回至少一行为止,而不是等到全部结束。在这里写任何有副作用的子查询都是不明智的(例如调用序列函数);这些副作用是否发生是很难判断的。

因为结果只取决于是否会返回行,而不取决于这些行的内容,所以这个子查询的输出列表通常是无关紧要的。一个常用的编码习惯是用EXISTS(SELECT 1 WHERE ...)的形式写所有的EXISTS测试。不过这条规则有例外,例如那些使用INTERSECT的子查询。

下面这个简单的示例类似在col2上的一次内连接,但是它为每个 tab1的行最多生成一行输出,即使存在多个匹配tab2的行也如此:

SELECT col1
FROM tab1
WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2);

6.15.2. IN(标量形式)

expression IN (value[, ...])

这种形式的 IN 的右边是一个由圆括号括起的标量表达式列表。如果左边表达式的结果等于任何一个右边表达式,结果为“真”。这是一种简写记法:

expression = value1
OR
expression = value2
OR
...

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

注意

这种形式的 IN 并不是真正的子查询表达式,但把它与子查询 IN 记录在同一地方似乎最合适。

6.15.3. IN(子查询形式)

expression IN (subquery)

这种形式的 IN 的右边是一个带圆括号的子查询,它必须恰好返回一列。左边的表达式被求值并与子查询结果的每一行比较。如果找到任何相等的子查询行,IN 的结果为“真”。如果没有找到相等的行(包括子查询不返回行的特殊情况),结果为“假”。

请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。

和EXISTS一样,假定子查询一定会完整运行并不明智。

(expression [, expression ...]) IN (subquery)

这种形式的 IN 的右边是一个带圆括号的子查询,它必须返回与左边列表中表达式数量完全相同的列。左边的表达式被求值并与子查询结果的每一行逐行比较。如果找到任何相等的子查询行,IN 的结果为“真”。如果没有找到相等的行(包括子查询不返回行的特殊情况),结果为“假”。

与通常一样,表达式或子查询行中的空值按照 SQL 布尔表达式的正常规则组合。如果两个行的所有对应成员都非空且相等,则认为它们相等;如果任何对应成员非空且不相等,则两行不相等;否则该行比较的结果为未知(空)。如果所有行比较的结果要么不相等要么为空,且至少有一个为空,那么 IN 的结果为空值。

6.15.4. NOT IN(标量形式)

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

这种形式的 NOT IN 的右边是一个由圆括号括起的标量表达式列表。如果左边表达式的结果与所有右边表达式都不相等,结果为“真”。这是一种简写记法:

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

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

提示

x NOT IN y在任何情况下都等价于NOT (x IN y)。不过,对新手来说,使用NOT IN时 null 值比使用IN时更容易造成困扰。最好尽可能用肯定的形式表达你的条件。

6.15.5. NOT IN(子查询形式)

expression NOT IN (subquery)

这种形式的 NOT IN 的右边是一个带圆括号的子查询,它必须恰好返回一列。左边的表达式被求值并与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回行的特殊情况),NOT IN 的结果为“真”。如果找到任何相等的行,结果为“假”。

请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。

和EXISTS一样,假定子查询一定会完整运行并不明智。

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

这种形式的 NOT IN 的右边是一个带圆括号的子查询,它必须返回与左边列表中表达式数量完全相同的列。左边的表达式被求值并与子查询结果的每一行逐行比较。如果只找到不相等的子查询行(包括子查询不返回行的特殊情况),NOT IN 的结果为“真”。如果找到任何相等的行,结果为“假”。

与通常一样,表达式或子查询行中的空值按照 SQL 布尔表达式的正常规则组合。如果两个行的所有对应成员都非空且相等,则认为它们相等;如果任何对应成员非空且不相等,则两行不相等;否则该行比较的结果为未知(空)。如果所有行比较的结果要么不相等要么为空,且至少有一个为空,那么 NOT IN 的结果为空值。

6.15.6. ANY/SOME

expression operator ANY (subquery)
expression operator SOME (subquery)

这种形式的 ANY 的右边是一个带圆括号的子查询,它必须恰好返回一列。左边的表达式使用给定的 operator 与子查询结果的每一行比较,该操作符必须产生布尔结果。如果得到任何真结果,ANY 的结果为“真”。如果没有找到真结果(包括子查询不返回行的特殊情况),结果为“假”。

SOME是ANY的同义词。IN等价于= ANY。

注意,如果没有任何成功的比较,并且至少有一个右侧行的操作符结果为 null,则ANY结构的结果将是 null 而不是假。这符合 SQL 对空值布尔组合的正常规则。

和EXISTS一样,假定子查询一定会完整运行并不明智。

(expression [, expression ...]) operator ANY (subquery)
(expression [, expression ...]) operator SOME (subquery)

这种形式的 ANY 的右边是一个带圆括号的子查询,它必须返回与左边列表中表达式数量完全相同的列。左边的表达式使用给定的 operator 与子查询结果的每一行逐行比较。目前,逐行 ANY 查询中只允许使用 = 和 <> 操作符。相应地,如果找到相等或不等的行,ANY 的结果为“真”。如果没有找到这样的行(包括子查询不返回行的特殊情况),结果为“假”。

与通常一样,表达式或子查询行中的空值按照 SQL 布尔表达式的正常规则组合。如果两个行的所有对应成员都非空且相等,则认为它们相等;如果任何对应成员非空且不相等,则两行不相等;否则该行比较的结果为未知(空)。如果至少有一个行比较结果为空值,那么 ANY 的结果不可能是假;它将是真或空值。

6.15.7. ALL

expression operator ALL (subquery)

这种形式的 ALL 的右边是一个带圆括号的子查询,它必须恰好返回一列。左边的表达式使用给定的 operator 与子查询结果的每一行比较,该操作符必须产生布尔结果。如果所有行都产生真(包括子查询不返回行的特殊情况),ALL 的结果为“真”。如果找到任何假结果,结果为“假”。

NOT IN等价于<> ALL。

注意,如果没有任何失败,但至少有一个右侧行的操作符结果为 null,则ALL结构的结果将是 null 而不是真。这符合 SQL 对空值布尔组合的正常规则。

和EXISTS一样,假定子查询一定会完整运行并不明智。

(expression [, expression ...]) operator ALL (subquery)
   

这种形式的 ALL 的右边是一个带圆括号的子查询,它必须返回与左边列表中表达式数量完全相同的列。左边的表达式使用给定的 operator 与子查询结果的每一行逐行比较。目前,逐行 ALL 查询中只允许使用 = 和 <> 操作符。相应地,如果所有子查询行都相等或都不相等(包括子查询不返回行的特殊情况),ALL 的结果为“真”。相应地,如果发现任何一行不相等或相等,结果为“假”。

与通常一样,表达式或子查询行中的空值按照 SQL 布尔表达式的正常规则组合。如果两个行的所有对应成员都非空且相等,则认为它们相等;如果任何对应成员非空且不相等,则两行不相等;否则该行比较的结果为未知(空)。如果至少有一个行比较结果为空值,那么 ALL 的结果不可能是真;它将是假或空值。

6.15.8. 按行比较

(expression [, expression ...]) operator (subquery)
(expression [, expression ...]) operator (expression [, expression ...])
   

左边是标量表达式的列表。右边既可以是相同长度的标量表达式列表,也可以是一个带圆括号的子查询,该子查询必须恰好返回与左边表达式数量相同的列。此外,子查询不能返回多于一行。(如果它返回零行,结果视为空值。)左边被求值并与子查询结果的唯一一行或右边的表达式列表逐行比较。目前,逐行比较中只允许使用 = 和 <> 操作符。相应地,如果这两行相等或不相等,结果为“真”。

与通常一样,表达式或子查询行中的空值按照 SQL 布尔表达式的正常规则组合。如果两个行的所有对应成员都非空且相等,则认为它们相等;如果任何对应成员非空且不相等,则两行不相等;否则该行比较的结果为未知(空)。如果至少有一个行比较结果为空值,那么行比较的结果为未知(空)。

报告文档问题

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