↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

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 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2
历史版本PostgreSQL 7.2 已于 2007 年 2 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本。

4.15. 子查询表达式 #

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

EXISTS

EXISTS ( subquery )

EXISTS 的参数是一个任意的 SELECT 语句,即 子查询。对 子查询求值以确定它是否返回任何行。 如果它返回至少一行,EXISTS 的结果是 TRUE;如果子查询不返回行,EXISTS 的结果 是 FALSE。

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

子查询通常只会执行到足以确定 是否至少返回一行,而不会完全执行到结束。 编写有副作用的子查询(如调用序列函数)是不明智的;副作用是否发生 可能难以预测。

由于结果只取决于是否返回任何行, 而不取决于这些行的内容,子查询的输出 列表通常无关紧要。一个常见的编码惯例是把所有 EXISTS 测试写成 EXISTS(SELECT 1 WHERE ...) 的形式。但 这条规则也有例外,比如使用 INTERSECT 的子查询。

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

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

IN (scalar form)

expression IN (value[, ...])

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

expression = value1
OR
expression = value2
OR
...

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

注意

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

IN (subquery form)

expression IN (subquery)

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

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

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

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

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

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

NOT IN (scalar form)

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

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

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

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

提示

x NOT IN y 在所有情况下都等价于 NOT (x IN y)。但是,使用 NOT IN 时 NULL 比使用 IN 时更容易让新手 犯错。如果可能,最好用肯定的形式表达你的条件。

NOT IN (subquery form)

expression NOT IN (subquery)

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

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

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

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

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

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

ANY

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

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

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

注意,如果没有成功且至少一个右边行对操作符的结果产生 NULL,ANY 结构的结果 将是 NULL 而不是 FALSE。 这符合 SQL 对 NULL 布尔组合的正常 规则。

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

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

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

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

ALL

expression operator ALL (subquery)

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

NOT IN等价于<> ALL。

注意,如果没有失败但至少一个右边行对操作符的结果产生 NULL,ALL 结构的结果 将是 NULL 而不是 TRUE。 这符合 SQL 对 NULL 布尔组合的正常 规则。

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

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

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

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

Row-wise comparison

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

左边是标量表达式的列表。右边 既可以是相同长度的标量表达式列表,也可以是一个 带圆括号的子查询,该子查询必须恰好返回与左边 表达式数量相同的列。此外,子查询不能 返回多于一行。(如果它返回零行,结果视为 NULL。)左边被求值并与 子查询结果的唯一一行或右边的表达式列表 逐行比较。相应地,如果这两行相等或不相等,结果为 TRUE。

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

提交更正

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