本节描述
PostgreSQL
里面与
SQL
兼容的子查询表达式。所有本节中的表达式都返回布尔值(真/假)结果。
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);
expression IN (subquery)
右边是一个圆括弧括起来的子查询,它必须只返回一个字段。
左边表达式对子查询结果的每一行进行一次计算和比较。如果找到任何相等的子查询行,
则
IN
结果为
"真"
。如果没有找到任何相等行,则结果为
"假"
(包括子查询没有返回任何行的情况)。
请注意,如果左边表达式的值为 NULL ,或者没有相等的右边值并且至少有一个右边行生成 NULL ,
那么
IN
的结果将是 NULL ,而不是假。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。
和
EXISTS
一样,假设子查询将被完全运行是不明智的。
row_constructor IN (subquery)
左边是一个行构造器(如
第 4.2.13 节
所述),右边是一个圆括弧括起来的子查询,
它必须返回和左边行构造器一样多的字段。左边表达式对子查询结果的每一行进行一次计算和比较。
如果找到相等的子查询行,则
IN
结果为
"真"
。如果没有找到任何相等行,
则结果为
"假"
(包括子查询没有返回任何行的情况)。
表达式或子查询行里的 NULL 遵照 SQL 处理布尔值和 NULL 组合时的规则。
如果两个行对应的字段都相等且非空,那么这两行相等;如果任意对应字段不等且非空,
那么这两行不等;否则结果是未知(NULL)。如果每一行的结果都是不等或 NULL ,
并且至少有一个 NULL ,那么
IN
的结果是 NULL 。
expression NOT IN (subquery)
右边是一个圆括弧括起来的子查询,它必须只返回一个字段。
左边表达式对子查询结果的每一行进行一次计算和比较。如果只找到不相等的子查询行
(包括子查询没有返回任何行的情况),则
NOT IN
结果为
"真"
。
如果找到任何相等行,则结果为
"假"
。
请注意,如果左边表达式的值为 NULL ,或者没有相等的右边值并且至少有一个右边行生成 NULL ,
那么
NOT IN
的结果将是 NULL ,而不是真。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。
和
EXISTS
一样,假设子查询将被完全运行是不明智的。
row_constructor NOT IN (subquery)
左边是一个行构造器(如
第 4.2.13 节
所述),
右边是一个圆括弧括起来的子查询,它必须返回和左边行构造器一样多的字段。
左边表达式对子查询结果的每一行进行一次计算和比较。如果只出现不相等的子查询行,
则
NOT IN
结果为
"真"
。(包括子查询没有返回任何行的情况)。
如果找到相等的子查询行,则结果为
"假"
。
表达式或子查询行里的 NULL 遵照 SQL 处理布尔值和 NULL 组合时的规则。
如果两个行对应的字段都相等且非空,那么这两行相等;如果任意对应字段不等且非空,
那么这两行不等;否则结果是未知(NULL)。如果每一行的结果都是不等或 NULL ,
并且至少有一个 NULL ,那么
NOT IN
的结果是 NULL 。
expression operator ANY (subquery)
expression operator SOME (subquery)
右边是一个圆括弧括起来的子查询,它必须只返回一个字段。
左边表达式使用
operator
对子查询结果的每一行进行一次计算和比较,
其结果必须是布尔值。如果至少获得一个真值,则
ANY
结果为
"真"
。
如果全部获得假值,则结果是
"假"
(包括子查询没有返回任何行的情况)。
SOME
是
ANY
的同意词。
IN
等效于
= ANY
。
请注意,如果没有获得任何真值并且至少有一个右边行在该操作符上生成 NULL ,
那么
ANY
的结果将是 NULL ,而不是假。
这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。
和
EXISTS
一样,假设子查询将被完全运行是不明智的。
row_constructor operator ANY (subquery)
row_constructor operator SOME (subquery)
左边是一个行构造器(如
第 4.2.13 节
所述),
右边是一个圆括弧括起来的子查询,它必须返回和左边行构造器一样多的字段。
左边表达式使用
operator
对子查询结果的每一行进行一次计算和比较。
如果至少获得一个真值,则
ANY
结果为
"真"
。
如果全部获得假值,则结果是
"假"
(包括子查询没有返回任何行的情况)。
如果没有获得任何真值并且至少有一个行返回 NULL ,那么结果将是 NULL。
查看
第 9.23.5 节
获取关于行构造比较含义的细节。
expression operator ALL (subquery)
右边是一个圆括弧括起来的子查询,它必须只返回一个字段。
左边表达式使用
operator
对子查询结果的每一行进行一次计算和比较,
其结果必须是布尔值。如果全部获得真值,
ALL
结果为
"真"
(包括子查询没有返回任何行的情况)。如果至少获得一个假值,则结果是
"假"
。
如果比较不会返回任何假值,并且至少一个行返回 NULL,则结果为 NULL。
NOT IN
等效于
<> ALL
。
和
EXISTS
一样,假设子查询将被完全运行是不明智的。
row_constructor operator ALL (subquery)
左边是一个行构造器(如
第 4.2.13 节
所述),
右边是一个圆括弧括起来的子查询,它必须返回和左边行构造器一样多的字段。
左边表达式使用
operator
对子查询结果的每一行进行一次计算和比较。
如果全部获得真值,
ALL
结果为
"真"
(包括子查询没有返回任何行的情况)。如果至少获得一个假值,则结果是
"假"
。
如果比较不会返回任何假值,并且至少一个行返回 NULL,则结果为 NULL。
查看
第 9.23.5 节
以获取关于行构造比较含义的细节。
row_constructor operator (subquery)
左边是一个行构造器(如
第 4.2.13 节
所述),
右边是一个圆括弧括起来的子查询,它必须返回和左边行构造器一样多的字段。
而且,该子查询不能返回超过 1 行结果(返回零行相当于 NULL)。
左边表达式对子查询的唯一结果行进行计算和比较。
查看
第 9.23.5 节
以获取关于行构造比较含义的细节。