本节描述 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 的这种形式的右手边是一个圆括弧括起来的子查询, 它必须只返回一列。左手边表达式对子查询的结果的每一行进行一次计算和 比较。如果找到任何等于子查询行的情况,那么 IN 的结果就是 "真"。如果没有找到相等行,那么结果是"假"(包括子查询没有返回任何行 的特殊例子)。
请注意如果左手边表达式生成 NULL,或者没有相等的右手边数值, 并且至少有一个右手边行生成 NULL,那么 IN 构造的 结果将是 NULL,而不是 FALSE。这个行为是遵照 SQL 处理布尔和 NULL 值组合时的规则定的。
和 EXISTS 一样,假设子查询将被完成运行完全是不明智的。
(expression, expression[, ...]) IN (subquery)
这种形式的 IN 的右手边是一个圆括弧括起来的子查询, 它必须返回和左手边表达式列表中完全一样多的字段。 左手边表达式就子查询结果的每一行进行计算很比较。如果找到任意 相等的子查询行,则 IN 的结果为"真"。如果没有找到相等行, 那么结果为"假"(包括子查询不返回行的特殊例子)。
通常,表达式或者子查询行里的 NULL 是按照 SQL 布尔表达式的一般规则 进行组合的。如果两个行对应的成员都是非空并且相等,那么认为这两行 相等;如果任意对应成员为非空且不等,那么该两行不等; 否则这样的行比较的结果是未知(NULL)。如果所有行的结果要么是不等, 要么是 NULL,并且至少有一个 NULL,那么 IN 的结果是 NULL。
expression NOT IN (subquery)
NOT IN 的这种形式的右手边是一个圆括弧括起来的子查询, 它必须只返回一列。左手边表达式对子查询的结果的每一行进行一次计算和 比较。如果只出现不等于子查询行的情况,那么 NOT IN 的结果就是 "真"。(包括子查询没有返回任何行的特殊例子)。 如果找到相等行,那么结果是"假"。
和通常一样,表达式或者子查询行里的 NULL 是按照 SQL 布尔表达式的一般规则 进行组合的。如果两个行对应的成员都是非空并且相等,那么认为这两行 相等;如果任意对应成员为非空且不等,那么该两行不等; 否则这样的行比较的结果是未知(NULL)。如果所有行的结果要么是不等, 要么是 NULL,并且至少有一个 NULL,那么 NOT IN 的结果是 NULL。
expression operator ANY(subquery) expression operator SOME (subquery)
ANY 的这种形式的右手边是一个圆括弧括起来的子查询, 它必须只返回一列。左手边表达式将使用给出的 operator对子查询的结果的每一行进行一次计算和 比较。该操作符必须生成布尔结果。 如果获得任何真值结果,那么 ANY 的结果就是 "真"。如果没有找到真值结果,那么结果是"假"(包括子查询没有返回任何行 的特殊例子)。
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 的结果就是 "真"。如果没有找到这样的行,那么结果是"假"(包括子查询没有返回任何行 的特殊例子)。
通常,表达式或者子查询行里的 NULL 是按照 SQL 布尔表达式的一般规则 进行组合的。如果两个行对应的成员都是非空并且相等,那么认为这两行 相等;如果任意对应成员为非空且不等,那么该两行不等; 否则这样的行比较的结果是未知(NULL)。如果至少有一个 NULL 行结果, 那么 ANY 的结果将是TRUE 或者 NULL。
expression operator ALL(subquery)
ALL 的这种形式的右手边是一个圆括弧括起来的子查询, 它必须只返回一列。左手边表达式将使用给出的 operator对子查询的结果的每一行进行一次计算和 比较。该操作符必须生成布尔结果。 如果所有行的结果都为"真",(包括子查询没有返回任何行的特殊例子)。 那么 ALL 的结果就是 "真"。如果没有存在任何假值结果,那么结果是"假"。
NOT IN 等效于 <> ALL。
请注意如果没有运算失败但是至少有一个右手边行为该操作符的结果 生成 NULL 值,那么 ALL 构造的结果将是 NULL,而不是 TRUE。 这个行为是遵照 SQL 处理布尔和 NULL 值组合时的一般规则定的。
和 EXISTS 一样,假设子查询将被完成运行完全是不明智的。
(expression, expression[, ...]) operator ALL (subquery)
ALL 的这种形式的右手边是一个圆括弧括起来的子查询, 它必须返回和左手边列表给出的表达式一样多的列。左手边表达式将使用给出的 operator对子查询的结果的每一行进行一次计算和 比较。目前系统只允许使用 = 和 <> 操作符处理逐行的 ALL 查询。 如果所有子查询都是相等或者不相等的行,那么 ALL 的结果就是 "真"。(包括子查询没有返回任何行的特殊例子)。 如果分别有任何不相等或者相等的行,那么结果是"假"。
通常,表达式或者子查询行里的 NULL 是按照 SQL 布尔表达式的一般规则 进行组合的。如果两个行对应的成员都是非空并且相等,那么认为这两行 相等;如果任意对应成员为非空且不等,那么该两行不等; 否则这样的行比较的结果是未知(NULL)。如果至少有一个 NULL 行结果, 那么 ALL 的结果就不可能是TRUE;它将会是 FALSE 或者 NULL。
(expression [, expression ...]) operator (subquery)
左手边是一个标量表达式列表。右手边可以是一个等长的标量表达式的列表, 或者一个圆括弧括起来的子查询,该查询必须返回很左手边表达式数目完全 一样的字段。另外,该子查询不能返回超过一行的数量。(如果它返回零行, 那么结果就是 NULL。)左手边逐行与右手边的子查询结果行,或者右手边 表达式列表进行比较。目前,只允许使用 = 和 <> 操作符进行逐行比较。 如果两行分别是相等或者不等,那么结果为"真"。
通常,表达式或者子查询行里的 NULL 是按照 SQL 布尔表达式的一般规则 进行组合的。如果两个行对应的成员都是非空并且相等,那么认为这两行 相等;如果任意对应成员为非空且不等,那么该两行不等; 否则这样的行比较的结果是未知(NULL)。