Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

9.24. 子查询表达式 #

9.24.1. EXISTS
9.24.2. IN
9.24.3. NOT IN
9.24.4. ANY/SOME
9.24.5. ALL
9.24.6. 单行比较

本节介绍SQL-兼容子查询表达式,适用于 PostgreSQL。本节介绍的所有表达式形式都返回布尔(真/假)结果。

9.24.1. EXISTS #

EXISTS (subquery)

EXISTS 的参数是一个任意的 SELECT 语句或 子查询。对子查询进行评估,确定它是否返回任何行。如果它返回至少一行,则 EXISTS 的结果为 true;如果子查询没有返回任何行,EXISTS 的结果为 false

子查询可以引用包围查询中的变量,在子查询执行期间,这些变量将作为常量。

子查询通常仅执行较短的时间以确定是否返回至少一行,而不是完全执行。编写具有副作用(例如调用序列函数)的子查询是不明智的;副作用会发生是不确定的。

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

这个简单的示例类似于在 col2 上的内部连接,但只会为每个 tab1 行生成最多一行输出,即使有多个匹配的 tab2 行。

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

9.24.2. IN #

expression IN (subquery)

右侧是一个括号内的子查询,它必须返回正好一列。对左侧表达式求值,并将表达式与子查询结果的每一行进行比较。IN 的结果为 true,如果找到任何相等的子查询行。如果未找到相等行(包括子查询不返回任何行的这种情况),则结果为 false

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

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

row_constructor IN (subquery)

这种形式的 IN 的左侧是一个行构造函数,如 4.2.13 节 中所述。右侧是一个括号内的子查询,它必须返回与左侧行中的表达式完全一样多的列。对左侧表达式求值,并逐行将其与子查询结果的每一行进行比较。IN 的结果为 true,如果找到任何相等的子查询行。如果未找到相等行(包括子查询不返回任何行的这种情况),则结果为 false

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

9.24.3. NOT IN #

expression NOT IN (subquery)

右侧是带括号的子查询,它必须返回恰好一列。计算左侧表达式,并将其与子查询结果的每一行进行比较。如果只发现不相等的子查询行(包括子查询未返回任何行的这种情况),NOT IN 的结果为 true如果找到任何相等的行,则结果为 false

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

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

row_constructor NOT IN (subquery)

这种形式 NOT IN 的左侧是一个行构造器,如 第 4.2.13 节 所述。右侧是带括号的子查询,它必须返回与左侧行中的表达式完全相等的列数。计算左侧表达式,并将其逐行与子查询结果的每一行进行比较。如果只发现不相等的子查询行(包括子查询未返回任何行的这种情况),NOT IN 的结果为 true如果找到任何相等的行,则结果为 false

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

9.24.4. ANY/SOME #

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

右侧是一个括号子查询,该子查询必须返回恰好一列。求值左侧表达式,并使用给定的运算符将其与子查询结果的每一行进行比较,该运算符必须产生布尔结果。如果获得任何真结果,则ANY的结果为true。如果没有找到真结果(包括子查询不返回任何行的情况),则结果为false

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

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

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

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

ANY表单的左侧是行构造函数,如第4.2.13节中所述。右侧是一个括号子查询,它必须返回列数与左侧行中的表达式数完全相等。求值左侧表达式,并使用给定的运算符逐行将其与子查询结果的每一行进行比较。如果比较对任何子查询行返回true,则ANY的结果为true。如果比较对每个子查询行(包括子查询不返回任何行的情况)返回false,则结果为false。如果与子查询行的任何比较未返回true,并且至少有一个比较返回NULL,则结果为NULL。

请参阅第9.25.5节以详细了解行构造函数比较的含义。

9.24.5. ALL #

expression operator ALL (subquery)

右侧是一个括号子查询,它必须返回恰好一列。求值左侧表达式,并使用给定的运算符将其与子查询结果的每一行进行比较,该运算符必须产生布尔结果。如果所有行都产生true(包括子查询不返回任何行的情况),则ALL的结果为true。如果找到任何假结果,则结果为false。如果与子查询行的任何比较未返回false,并且至少有一个比较返回NULL,则结果为NULL。

NOT IN 等同于 <> ALL

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

row_constructor operator ALL (subquery)

此形式 ALL 的左侧是一个行构造器,如 第 4.2.13 节 所述。右侧是一个带括号的子查询,它必须返回与左侧行的表达式一样多的列。左侧表达式经过评估并逐行与子查询结果的每一行相比较,使用给定的 operator。如果所有子查询行的比较结果都为真(包括子查询无返回行的情况),则 ALL 的结果为 true。如果任何子查询行的比较结果都为假,则结果为 false。如果与子查询行的比较结果均不为假,并且至少有一个比较结果为 NULL,则结果为 NULL。

请参阅第9.25.5节以详细了解行构造函数比较的含义。

9.24.6. 单行比较 #

row_constructor operator (subquery)

左侧是一个行构造器,如 第 4.2.13 节 所述。右侧是一个带括号的子查询,它必须返回与左侧行的表达式一样多的列。此外,子查询不能返回多于一行。(如果它返回零行,则结果将被视为 null。)左侧经过评估并逐行与单个子查询结果行进行比较。

请参阅第9.25.5节以详细了解行构造函数比较的含义。