选择 打开 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
测试与开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0
历史版本PostgreSQL 9.6 已于 2021 年 11 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本

9.22. 子查询表达式 #

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

9.22.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);

9.22.2. IN #

expression IN (subquery)

右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是。如果没有找到相等行,那么结果就是(包括子查询不返回任何行的情况)。

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

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

row_constructor IN (subquery)

这种形式的IN左手边是一个行构造器,如第 4.2.13 节中所述。右手边是一个圆括号括起来的子查询,它必须返回与左手边行中表达式数量完全相同的列数。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,则IN的结果为。如果没有找到相等行,那么结果为(包括子查询不返回任何行的情况)。

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

9.22.3. NOT IN #

expression NOT IN (subquery)

右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是。如果找到任何相等行,则结果为

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

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

row_constructor NOT IN (subquery)

这种形式的NOT IN左侧是一个行构造器,如第 4.2.13 节中所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。对左侧表达式求值后,将其按行与子查询结果的每一行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为。如果找到任何相等行,则结果为

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

9.22.4. ANY/SOME #

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

这种形式的右侧是一个用括号括起来的子查询,它必须恰好返回一列。左侧表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果得到任何真值结果,那么ANY的结果就是。如果没有找到真值结果,那么结果是(包括子查询没有返回任何行的情况)。

SOMEANY的同义词。IN等价于= ANY

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

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

row_constructor operator ANY (subquery)
row_constructor operator SOME (subquery)

这种形式的ANY左侧是一个行构造器,如第 4.2.13 节所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式数量完全相同的列数。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行逐行比较。如果比较对任何子查询行返回真,则ANY的结果为。如果比较对每一个子查询行都返回假,则结果为(包括子查询不返回行的情况)。如果比较对任何行都不返回真,并且至少有一次比较返回 NULL,则结果为 NULL。

关于行构造器比较的详细含义请见第 9.23.5 节

9.22.5. ALL #

expression operator ALL (subquery)

右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为。如果得到任何假值结果,则结果为。如果与任何子查询行的比较都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。

NOT IN等价于<> ALL

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

row_constructor operator ALL (subquery)

这种形式的 ALL 左侧是一个行构造器,如第 4.2.13 节所述。右侧是一个用括号括起来的子查询,它必须返回与左侧行中表达式一样多的列。左侧表达式会被求值,并使用给定的 operator 与子查询结果逐行比较。如果该比较对所有子查询行都返回真,那么ALL的结果就是(包括子查询没有返回任何行的情况)。如果对任何子查询行的比较返回假,则结果为。如果比较对任何子查询行都不返回假,并且至少有一次比较返回 NULL,则结果为 NULL。

关于行构造器比较的详细含义请见第 9.23.5 节

9.22.6. 单一行比较

row_constructor operator (subquery)

左侧是一个行构造器,如第 4.2.13 节所述。右侧是一个用圆括号括起来的子查询,必须返回与左侧行中表达式数量完全相同的列数。此外,该子查询不能返回超过一行;如果它返回零行,则结果为空值。对左侧求值后,将所得的行与子查询返回的唯一一行进行比较。

关于行构造器比较的详细含义请见第 9.23.5 节

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。