9.22. 子查询表达式

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

9.22.1. EXISTS

EXISTS (subquery)

EXISTS的参数是任意SELECT语句或* subquery *。评估子查询以确定它是否返回任何行。如果返回至少一行,则EXISTS的结果为“ true”;如果子查询不返回任何行,则EXISTS的结果为“ false”。

子查询可以引用来自周围查询的变量,这些变量将在子查询的任何一次评估期间充当常量。

子查询通常只会执行足够长的时间,以确定是否至少返回一行,而不是一直完成。编写具有副作用(例如调用序列函数)的子查询是不明智的。副作用是否发生可能是无法预测的。

由于结果仅取决于是否返回任何行,而不取决于这些行的内容,因此子查询的输出列表通常不重要。通用的编码约定是以EXISTS(SELECT 1 WHERE ...)的形式编写所有EXISTS测试。但是,此规则也有 exception,例如使用INTERSECT的子查询。

这个简单的示例就像col2上的内部联接一样,但是即使有几条匹配的tab2行,它也为每个tab1行最多生成一个输出行:

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

9.22.2. IN

expression IN (subquery)

右侧是带括号的子查询,该查询必须仅返回一列。评估左侧表达式并将其与子查询结果的每一行进行比较。如果找到相等的子查询行,则IN的结果为“ true”。如果找不到相等的行,则结果为“ false”(包括子查询不返回任何行的情况)。

请注意,如果左侧表达式的结果为 null,或者没有相等的右侧值,并且至少一个右侧行的结果为 null,则IN构造的结果将为 null,而不是 false。这符合 SQL 的空值布尔组合的常规规则。

EXISTS一样,假设子查询将被完全评估是不明智的。

row_constructor IN (subquery)

这种形式IN的左侧是行构造函数,如Section 4.2.13中所述。右侧是带括号的子查询,该子查询必须返回与左侧行中的表达式一样多的列。评估左侧表达式并将其逐行与子查询结果的每一行进行比较。如果找到相等的子查询行,则IN的结果为“ true”。如果找不到相等的行,则结果为“ false”(包括子查询不返回任何行的情况)。

通常,将按照 SQL 布尔表达式的常规规则合并行中的空值。如果两行的所有对应成员均为非 null 且相等,则认为两行相等;如果任何相应的成员为非空且不相等,则行不相等;否则,该行比较的结果未知(空)。如果所有每行结果都不相等或为 null,且至少有一个 null,则IN的结果为 null。

9 .22.3. 不在

expression NOT IN (subquery)

右侧是带括号的子查询,该查询必须仅返回一列。评估左侧表达式并将其与子查询结果的每一行进行比较。如果仅找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为“ true”。如果找到相等的行,则结果为“ false”。

请注意,如果左侧表达式产生 null,或者没有相等的右侧值并且至少一个右侧行产生 null,则NOT IN构造的结果将为 null,而不是 true。这符合 SQL 的空值布尔组合的常规规则。

EXISTS一样,假设子查询将被完全评估是不明智的。

row_constructor NOT IN (subquery)

这种形式NOT IN的左侧是行构造函数,如Section 4.2.13中所述。右侧是带括号的子查询,该子查询必须返回与左侧行中的表达式一样多的列。评估左侧表达式并将其逐行与子查询结果的每一行进行比较。如果仅找到不相等的子查询行(包括子查询不返回任何行的情况),则NOT IN的结果为“ true”。如果找到相等的行,则结果为“ false”。

通常,将按照 SQL 布尔表达式的常规规则合并行中的空值。如果两行的所有对应成员均为非 null 且相等,则认为两行相等;如果任何相应的成员为非空且不相等,则行不相等;否则,该行比较的结果未知(空)。如果所有每行结果都不相等或为 null,且至少有一个 null,则NOT IN的结果为 null。

9.22.4. ANY/SOME

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

右侧是带括号的子查询,该查询必须仅返回一列。使用给定的* operator *评估左手表达式并将其与子查询结果的每一行进行比较,后者必须产生布尔结果。如果获得任何真结果,则ANY的结果为“真”。如果找不到正确的结果(包括子查询不返回任何行的情况),则结果为“ false”。

SOMEANY的同义词。 IN等效于= ANY

请注意,如果没有成功,并且至少一个右侧行的运算符结果为 null,则ANY构造的结果将为 null,而不是 false。这符合 SQL 的空值布尔组合的常规规则。

EXISTS一样,假设子查询将被完全评估是不明智的。

row_constructor operator ANY (subquery)
row_constructor operator SOME (subquery)

这种形式ANY的左侧是行构造函数,如Section 4.2.13中所述。右侧是带括号的子查询,该子查询必须返回与左侧行中的表达式一样多的列。使用给定的* operator *评估左侧表达式并将其逐行与子查询结果的每一行进行比较。如果比较对于任何子查询行返回 true,则ANY的结果为“ true”。如果比较为每个子查询行返回 false(包括子查询不返回任何行的情况),则结果为“ false”。如果没有与子查询行的比较返回 true,则结果为 NULL,并且至少一个比较返回 NULL。

有关行构造函数比较的含义的详细信息,请参见Section 9.23.5

9.22.5. ALL

expression operator ALL (subquery)

右侧是带括号的子查询,该查询必须仅返回一列。使用给定的* operator *评估左手表达式并将其与子查询结果的每一行进行比较,后者必须产生布尔结果。如果所有行都为真(包括子查询不返回任何行的情况),则ALL的结果为“真”。如果发现任何错误结果,则结果为“ false”。如果没有与子查询行的比较返回 false,则结果为 NULL,并且至少一个比较返回 NULL。

NOT IN等效于<> ALL

EXISTS一样,假设子查询将被完全评估是不明智的。

row_constructor operator ALL (subquery)

这种形式ALL的左侧是行构造函数,如Section 4.2.13中所述。右侧是带括号的子查询,该子查询必须返回与左侧行中的表达式一样多的列。使用给定的* operator *评估左侧表达式并将其逐行与子查询结果的每一行进行比较。如果比较对所有子查询行都返回 true(包括子查询不返回行的情况),则ALL的结果为“ true”。如果比较对于任何子查询行返回 false,则结果为“ false”。如果没有与子查询行的比较返回 false,则结果为 NULL,并且至少一个比较返回 NULL。

有关行构造函数比较的含义的详细信息,请参见Section 9.23.5

9 .22.6. 单行比较

row_constructor operator (subquery)

左侧是行构造器,如Section 4.2.13中所述。右侧是带括号的子查询,该子查询必须返回与左侧行中的表达式一样多的列。此外,子查询不能返回多于一行。 (如果返回零行,则结果为 null.)将评估左侧并将其按行与单个子查询结果行进行比较。

有关行构造函数比较的含义的详细信息,请参见Section 9.23.5