pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
本节描述 PostgreSQL 中可用的 SQL 兼容的子查询表达式。 本节中记录的所有表达式形式都返回布尔值(真/假)结果。
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);
INexpressionIN (subquery)
右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果找到任意相等的子查询行,那么IN的结果就是“真”。如果没有找到相等行,那么结果就是“假”(包括子查询不返回任何行的情况)。
请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则IN结构的结果将是空值,而不是假。这符合 SQL 对空值布尔组合的一般规则。
和EXISTS一样,假定子查询一定会完整运行并不明智。
(expression[,expression...]) IN (subquery)
这种形式的 IN 的右边是一个带圆括号的 子查询,它必须返回与左边列表中 表达式数量完全相同的列。左边的表达式 被求值并与子查询结果的每一行 逐行比较。如果找到任何相等的子查询行, IN 的结果为“真”。 如果没有找到相等的行(包括子查询 不返回行的特殊情况),结果为“假”。
通常,表达式或者子查询行里的空值是按照 SQL 布尔表达式的一般规则进行组合的。如果两个行对应的成员都非空并且相等,那么认为这两行相等;如果任意对应成员为非空且不等,那么这两行不等;否则这样的行比较的结果是未知(空值)。如果所有行的结果要么是不等,要么是空值,并且至少有一个空值,那么IN的结果是空值。
NOT INexpressionNOT IN (subquery)
右手边是一个圆括号括起来的子查询,它必须恰好返回一列。左手边表达式会被求值,并与子查询结果逐行比较。如果只找到不相等的子查询行(包括子查询不返回任何行的情况),那么NOT IN的结果是“真”。如果找到任何相等行,则结果为“假”。
请注意,如果左侧表达式得到空值,或者右侧没有相等的值且至少有一行得到空值,则NOT IN结构的结果将是空值,而不是真。这符合 SQL 对空值布尔组合的一般规则。
和EXISTS一样,假定子查询一定会完整运行并不明智。
(expression[,expression...]) NOT IN (subquery)
这种形式的 NOT IN 的右边是一个带圆括号的 子查询,它必须返回与左边列表中 表达式数量完全相同的列。左边的表达式 被求值并与子查询结果的每一行 逐行比较。如果只找到不相等的子查询行 (包括子查询不返回行的特殊情况), NOT IN 的结果为“真”。 如果找到任何相等的行,结果为“假”。
通常,表达式或者子查询行里的空值是按照 SQL 布尔表达式的一般规则进行组合的。如果两个行对应的成员都非空并且相等,那么认为这两行相等;如果任意对应成员为非空且不等,那么这两行不等;否则这样的行比较的结果是未知(空值)。如果所有行的结果要么是不等,要么是空值,并且至少有一个空值,那么NOT IN的结果是空值。
ANY/SOMEexpressionoperatorANY (subquery)expressionoperatorSOME (subquery)
右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果得到任何真值结果,则ANY的结果为“真”。如果没有找到真值结果(包括子查询不返回任何行的情况),则结果为“假”。
SOME是ANY的同义词。IN等价于= ANY。
注意,如果没有任何成功的比较,并且至少有一个右侧行的操作符结果为 null,则ANY结构的结果将是 null 而不是假。这符合 SQL 对空值布尔组合的正常规则。
和EXISTS一样,假定子查询一定会完整运行并不明智。
(expression[,expression...])operatorANY (subquery) (expression[,expression...])operatorSOME (subquery)
这种形式的 ANY 的右边是一个带圆括号的 子查询,它必须返回与左边列表中 表达式数量完全相同的列。左边的表达式 使用给定的 operator 与子查询结果的每一行 逐行比较。目前, 逐行 ANY 结构中只允许使用 = 和 <> 操作符。 相应地,如果找到相等或不等的行, ANY 的结果为“真”。 如果没有找到这样的行(包括子查询 不返回行的特殊情况),结果为“假”。
和通常一样,行中的空值按照 SQL 布尔表达式的正常规则进行组合。如果两个行的所有对应成员都非空且相等,则认为两行相等;如果任何对应成员非空且不相等,则两行不相等;否则该行比较的结果为未知(null)。如果至少有一个行的结果为 null,则ANY的结果不可能是假;它将是真或 null。
ALLexpressionoperatorALL (subquery)
右侧是一个用圆括号括起来的子查询,必须恰好返回一列。左侧表达式会被求值,并使用给定的operator与子查询结果的每一行进行比较。该操作符必须产生布尔结果。如果所有行都得到真(包括子查询不返回任何行的情况),则ALL的结果为“真”。如果得到任何假值结果,则结果为“假”。
NOT IN等价于<> ALL。
注意,如果没有任何失败,但至少有一个右侧行的操作符结果为 null,则ALL结构的结果将是 null 而不是真。这符合 SQL 对空值布尔组合的正常规则。
和EXISTS一样,假定子查询一定会完整运行并不明智。
(expression[,expression...])operatorALL (subquery)
这种形式的 ALL 的右边是一个带圆括号的 子查询,它必须返回与左边列表中 表达式数量完全相同的列。左边的表达式 使用给定的 operator 与子查询结果的每一行 逐行比较。目前, 逐行 ALL 查询中只允许使用 = 和 <> 操作符。 相应地,如果所有子查询行都相等 或都不相等(包括子查询 不返回行的特殊情况), ALL 的结果为“真”。 相应地,如果发现任何一行不相等或相等, 结果为“假”。
和通常一样,行中的空值按照 SQL 布尔表达式的正常规则进行组合。如果两个行的所有对应成员都非空且相等,则认为两行相等;如果任何对应成员非空且不相等,则两行不相等;否则该行比较的结果为未知(null)。如果至少有一个行的结果为 null,则ALL的结果不可能是真;它将是假或 null。
(expression[,expression...])operator(subquery)
左边是标量表达式的列表。右边是 一个带圆括号的子查询,它必须返回与左边 表达式数量完全相同的列。此外,子查询不能 返回多于一行。(如果它返回零行,结果视为 空值。)左边被求值并与 子查询结果的唯一一行 逐行比较。 目前,逐行比较中只允许使用 = 和 <> 操作符。 相应地,如果这两行相等或不相等,结果为“真”。
和通常一样,行中的空值按照 SQL 布尔表达式的正常规则进行组合。如果两个行的所有对应成员都非空且相等,则认为两行相等;如果任何对应成员非空且不相等,则两行不相等;否则该行比较的结果为未知(null)。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。