支持的版本: 当前 (17) / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 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

9.24. 子查询表达式 #

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

9.24.1. EXISTS #

EXISTS (subquery)

EXISTS 的参数是一个任意的 SELECT 语句,或者一个 子查询。评估子查询以确定它是否返回任何行。如果它返回至少一行,EXISTS 的结果为 true;如果子查询不返回任何行,EXISTS 的结果为 false

子查询可以引用来自周围查询的变量,这些变量在子查询的任何一次评估期间都充当常量。

子查询通常只执行足够长的时间来确定是否返回了至少一行,而不是一直执行到完成。编写具有副作用(例如调用序列函数)的子查询是不明智的;副作用是否发生可能是不可预测的。

由于结果仅取决于是否返回了任何行,而不取决于这些行的内容,因此子查询的输出列表通常是不重要的。一个常见的编码约定是以 EXISTS(SELECT 1 WHERE ...) 的形式编写所有 EXISTS 测试。但是,也有一些例外,例如使用 INTERSECT 的子查询。

这个简单的示例类似于在 col2 上的内连接,但是它为每个 tab1 行最多产生一个输出行,即使有多个匹配的 tab2

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

9.24.2. IN #

expression IN (subquery)

右侧是带括号的子查询,它必须只返回一列。评估左侧表达式并将其与子查询结果的每一行进行比较。如果找到任何相等的子查询行,IN 的结果为 true。如果没有找到相等的行(包括子查询不返回任何行的情况),则结果为 false

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

EXISTS 一样,假设子查询将被完全评估是不明智的。

row_constructor IN (subquery)

此形式的 IN 的左侧是一个行构造器,如 第 4.2.13 节所述。右侧是带括号的子查询,它必须返回与左侧行中的表达式数量完全相同的列数。评估左侧表达式,并将其与子查询结果的每一行进行行式比较。如果找到任何相等的子查询行,IN 的结果为 true。如果没有找到相等的行(包括子查询不返回任何行的情况),则结果为 false

与通常一样,行中的 null 值根据 SQL 布尔表达式的正常规则组合。如果它们的所有对应成员都是非 null 且相等的,则认为两行相等;如果任何对应成员是非 null 且不相等的,则认为两行不相等;否则,该行比较的结果是未知的(null)。如果所有每行的结果都是不相等或 null,并且至少有一个 null,则 IN 的结果为 null。

9.24.3. NOT IN #

expression NOT IN (subquery)

右侧是带括号的子查询,它必须只返回一列。评估左侧表达式并将其与子查询结果的每一行进行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则 NOT IN 的结果为 true。如果找到任何相等的行,则结果为 false

请注意,如果左侧表达式产生 null,或者如果没有相等的右侧值且至少有一个右侧行产生 null,则 NOT IN 构造的结果将为 null,而不是 true。这符合 SQL 关于 null 值的布尔组合的正常规则。

EXISTS 一样,假设子查询将被完全评估是不明智的。

row_constructor NOT IN (subquery)

此形式的 NOT IN 的左侧是一个行构造器,如 第 4.2.13 节所述。右侧是带括号的子查询,它必须返回与左侧行中的表达式数量完全相同的列数。评估左侧表达式,并将其与子查询结果的每一行进行行式比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),则 NOT IN 的结果为 true。如果找到任何相等的行,则结果为 false

与通常一样,行中的 null 值根据 SQL 布尔表达式的正常规则组合。如果它们的所有对应成员都是非 null 且相等的,则认为两行相等;如果任何对应成员是非 null 且不相等的,则认为两行不相等;否则,该行比较的结果是未知的(null)。如果所有每行的结果都是不相等或 null,并且至少有一个 null,则 NOT IN 的结果为 null。

9.24.4. ANY/SOME #

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

右侧是带括号的子查询,它必须只返回一列。使用给定的 operator 评估左侧表达式并将其与子查询结果的每一行进行比较,该 operator 必须产生布尔结果。如果获得任何 true 结果,则 ANY 的结果为 true。如果没有找到 true 结果(包括子查询不返回任何行的情况),则结果为 false

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

请注意,如果没有成功,并且至少有一个右侧行对操作符的结果产生 null,则 ANY 构造的结果将为 null,而不是 false。这符合 SQL 关于 null 值的布尔组合的正常规则。

EXISTS 一样,假设子查询将被完全评估是不明智的。

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

此形式的 ANY 的左侧是一个行构造器,如 第 4.2.13 节所述。右侧是带括号的子查询,它必须返回与左侧行中的表达式数量完全相同的列数。使用给定的 operator 评估左侧表达式,并将其与子查询结果的每一行进行行式比较。如果比较对任何子查询行返回 true,则 ANY 的结果为 true。如果比较对每个子查询行返回 false(包括子查询不返回任何行的情况),则结果为 false。如果与子查询行的比较都没有返回 true,并且至少有一个比较返回 NULL,则结果为 NULL。

有关行构造器比较的含义的详细信息,请参阅 第 9.25.5 节

9.24.5. ALL #

expression operator ALL (subquery)

右侧是一个带括号的子查询,它必须只返回一列。左侧的表达式会被求值,并使用给定的 operator 与子查询结果的每一行进行比较,该运算符必须产生布尔结果。如果所有行都产生 true(包括子查询不返回任何行的情况),则 ALL 的结果为 true。 如果发现任何 false 结果,则结果为 false。如果与子查询行的比较都没有返回 false,且至少有一个比较返回 NULL,则结果为 NULL。

NOT IN 等价于 <> ALL

EXISTS 一样,假设子查询将被完全评估是不明智的。

row_constructor operator ALL (subquery)

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

有关行构造器比较的含义的详细信息,请参阅 第 9.25.5 节

9.24.6. 单行比较 #

row_constructor operator (subquery)

左侧是一个行构造器,如 第 4.2.13 节 中所述。右侧是一个带括号的子查询,它必须返回的列数与左侧行中的表达式数量完全相同。此外,子查询不能返回多于一行。(如果它返回零行,则结果被视为 null。)左侧会被求值,并与单个子查询结果行进行逐行比较。

有关行构造器比较的含义的详细信息,请参阅 第 9.25.5 节

提交更正

如果您发现文档中有任何不正确、与您对特定功能的体验不符或需要进一步澄清的地方,请使用此表格报告文档问题。