本节描述 PostgreSQL 中可用的符合 SQL 标准的子查询表达式。 本节中记录的所有表达式形式都返回布尔 (真/假) 结果。
EXISTS #
EXISTS (subquery)
EXISTS
的参数是一条任意的
SELECT
语句,
亦即
子查询。
会对子查询进行求值,
以确定它是否返回任何行。
如果它至少返回一行,
那么
EXISTS
的结果为
“真”;
如果子查询不返回任何行,
那么
EXISTS
的结果为
“假”。
子查询可以引用外围查询中的变量, 这些变量在对子查询的任何一次求值期间都充当常量。
子查询通常只会被执行到足以确定是否至少返回一行为止, 而不会执行到全部完成。 编写带有副作用的子查询 (例如调用序列函数) 是不明智的; 副作用是否会发生可能是不可预测的。
由于结果只取决于是否返回了任何行,
而不取决于那些行的内容,
因此子查询的输出列表通常无关紧要。
一种常见的编码惯例是把所有
EXISTS
测试都写成
EXISTS(SELECT 1 WHERE ...)
的形式。
不过这条规则也有例外,
例如使用
INTERSECT
的子查询。
这个简单的例子就像是对
col2
的一个内连接,
但它为每条
tab1
行最多产生一个输出行,
即使有多条匹配的
tab2
行也是如此:
SELECT col1 FROM tab1 WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2);
IN #expressionIN (subquery)
右侧是一个被圆括号括起来的子查询,
它必须恰好返回一列。
会对左侧表达式求值,
并把它与子查询结果的每一行进行比较。
如果找到了任何相等的子查询行,
那么
IN
的结果为
“真”。
如果没有找到相等的行
(包括子查询不返回任何行的情况),
结果为
“假”。
注意,
如果左侧表达式得出空值,
或者没有相等的右侧值且至少有一个右侧行得出空值,
那么
IN
构造的结果将是空,
而非假。
这符合 SQL
对空值布尔组合的常规规则。
与 EXISTS
一样,
假定子查询会被完整地求值是不明智的。
row_constructorIN (subquery)
这种形式的
IN
的左侧是一个行构造器,
如
Section 4.2.13
中所述。
右侧是一个被圆括号括起来的子查询,
它必须返回恰好与左侧行中的表达式数量相同的列。
会对左侧表达式求值,
并按行与子查询结果的每一行进行比较。
如果找到了任何相等的子查询行,
那么
IN
的结果为
“真”。
如果没有找到相等的行
(包括子查询不返回任何行的情况),
结果为
“假”。
照例,
行中的空值会按照 SQL
布尔表达式的常规规则合并。
如果两行所有相应的成员都非空且相等,
则这两行被视为相等;
如果任何相应的成员非空且不相等,
则这两行不相等;
否则那次行比较的结果是未知的
(空)。
如果所有的逐行结果要么是不相等要么是空,
且至少有一个是空,
那么
IN
的结果为空。
NOT IN #expressionNOT IN (subquery)
右侧是一个被圆括号括起来的子查询,
它必须恰好返回一列。
会对左侧表达式求值,
并把它与子查询结果的每一行进行比较。
如果只找到了不相等的子查询行
(包括子查询不返回任何行的情况),
那么
NOT IN
的结果为
“真”。
如果找到了任何相等的行,
结果为
“假”。
注意,
如果左侧表达式得出空值,
或者没有相等的右侧值且至少有一个右侧行得出空值,
那么
NOT IN
构造的结果将是空,
而非真。
这符合 SQL
对空值布尔组合的常规规则。
与 EXISTS
一样,
假定子查询会被完整地求值是不明智的。
row_constructorNOT IN (subquery)
这种形式的
NOT IN
的左侧是一个行构造器,
如
Section 4.2.13
中所述。
右侧是一个被圆括号括起来的子查询,
它必须返回恰好与左侧行中的表达式数量相同的列。
会对左侧表达式求值,
并按行与子查询结果的每一行进行比较。
如果只找到了不相等的子查询行
(包括子查询不返回任何行的情况),
那么
NOT IN
的结果为
“真”。
如果找到了任何相等的行,
结果为
“假”。
照例,
行中的空值会按照 SQL
布尔表达式的常规规则合并。
如果两行所有相应的成员都非空且相等,
则这两行被视为相等;
如果任何相应的成员非空且不相等,
则这两行不相等;
否则那次行比较的结果是未知的
(空)。
如果所有的逐行结果要么是不相等要么是空,
且至少有一个是空,
那么
NOT IN
的结果为空。
ANY/SOME #expressionoperatorANY (subquery)expressionoperatorSOME (subquery)
右侧是一个被圆括号括起来的子查询,
它必须恰好返回一列。
会对左侧表达式求值,
并使用给定的
operator
与子查询结果的每一行进行比较,
该操作符必须产生一个布尔结果。
如果得到了任何真的结果,
那么
ANY
的结果为
“真”。
如果没有找到任何真的结果
(包括子查询不返回任何行的情况),
结果为
“假”。
SOME
是
ANY
的同义词。
IN
等同于
= ANY。
注意,
如果没有任何成功的比较,
且至少有一个右侧行对该操作符的结果得出空值,
那么
ANY
构造的结果将是空,
而非假。
这符合 SQL
对空值布尔组合的常规规则。
与 EXISTS
一样,
假定子查询会被完整地求值是不明智的。
row_constructoroperatorANY (subquery)row_constructoroperatorSOME (subquery)
这种形式的
ANY
的左侧是一个行构造器,
如
Section 4.2.13
中所述。
右侧是一个被圆括号括起来的子查询,
它必须返回恰好与左侧行中的表达式数量相同的列。
会对左侧表达式求值,
并使用给定的
operator
按行与子查询结果的每一行进行比较。
如果比较对任何子查询行返回真,
那么
ANY
的结果为
“真”。
如果比较对每个子查询行都返回假
(包括子查询不返回任何行的情况),
结果为
“假”。
如果与子查询行的比较没有返回真,
并且至少有一次比较返回 NULL,
则结果为 NULL。
关于行构造器比较的含义的细节, 请参见 Section 9.25.5。
ALL #expressionoperatorALL (subquery)
右侧是一个被圆括号括起来的子查询,
它必须恰好返回一列。
会对左侧表达式求值,
并使用给定的
operator
与子查询结果的每一行进行比较,
该操作符必须产生一个布尔结果。
如果所有行都得出真
(包括子查询不返回任何行的情况),
那么
ALL
的结果为
“真”。
如果找到了任何假的结果,
结果为
“假”。
如果与子查询行的比较没有返回假,
并且至少有一次比较返回 NULL,
则结果为 NULL。
NOT IN
等同于
<> ALL。
与 EXISTS
一样,
假定子查询会被完整地求值是不明智的。
row_constructoroperatorALL (subquery)
这种形式的
ALL
的左侧是一个行构造器,
如
Section 4.2.13
中所述。
右侧是一个被圆括号括起来的子查询,
它必须返回恰好与左侧行中的表达式数量相同的列。
会对左侧表达式求值,
并使用给定的
operator
按行与子查询结果的每一行进行比较。
如果比较对所有子查询行都返回真
(包括子查询不返回任何行的情况),
那么
ALL
的结果为
“真”。
如果比较对任何子查询行返回假,
结果为
“假”。
如果与子查询行的比较没有返回假,
并且至少有一次比较返回 NULL,
则结果为 NULL。
关于行构造器比较的含义的细节, 请参见 Section 9.25.5。
row_constructoroperator(subquery)
左侧是一个行构造器, 如 Section 4.2.13 中所述。 右侧是一个被圆括号括起来的子查询, 它必须返回恰好与左侧行中的表达式数量相同的列。 此外, 该子查询不能返回多于一行。 (如果它返回零行, 那么结果被视为空。) 会对左侧求值, 并按行与该唯一的子查询结果行进行比较。
关于行构造器比较的含义的细节, 请参见 Section 9.25.5。