子查询限制
以下限制适用于 Vertica 子查询:
-
子查询不可在
CREATE PROJECTION
语句的定义查询中使用。 -
子查询可以在
SELECT
列表中使用,但如果子查询不是包含查询的GROUP BY
子句的组成部分,则GROUP BY
或聚合函数不可在查询中使用。例如,以下两个语句会返回错误消息:=> SELECT y, (SELECT MAX(a) FROM t1) FROM t2 GROUP BY y; ERROR: subqueries in the SELECT or ORDER BY are not supported if the subquery is not part of the GROUP BY => SELECT MAX(y), (SELECT MAX(a) FROM t1) FROM t2; ERROR: subqueries in the SELECT or ORDER BY are not supported if the query has aggregates and the subquery is not part of the GROUP BY
-
支持在
UPDATE
语句中使用子查询,但存在以下例外:-
不能使用
SET column = {expression}
来指定子查询。 -
UPDATE
列表中指定的表也不能出现在FROM
子句中(没有自联接)。
-
-
FROM
子句子查询需要别名,但表不需要别名。如果表没有别名,查询必须将其中的列命名为 table-name.column-name。但是,在查询中的所有表之间均保持唯一的列名不需要由其表名来限定。 -
如果
ORDER BY
子句包含在FROM
子句子查询中,而不是包含在包含查询中,则查询可能会返回意外的排序结果。发生这种情况是因为 Vertica 数据来自多个节点,因此无法保证排序顺序,除非外部查询块指定ORDER BY
子句。这种行为符合 SQL 标准,但它有别于其他数据库。 -
多列子查询不能使用 <、>、<=、>= 比较运算符。它们可以使用 <>、!= 和 = 比较运算符。
-
WHERE
和HAVING
子句子查询必须使用布尔比较运算符:=、>、<、<>、<=、>=。这些子查询可以是非相关和相关子查询。 -
[NOT] IN
和ANY
子查询(嵌套在另一个表达式中)在以下情况下不受支持:任一列值为 NULL。例如,在以下语句中,如果表t1
或t2
中的列 x 包含 NULL 值,Vertica 将返回运行时错误:=> SELECT * FROM t1 WHERE (x IN (SELECT x FROM t2)) IS FALSE; ERROR: NULL value found in a column used by a subquery
-
Vertica 将在标量子查询(返回多行)的子查询运行期间返回错误消息。
-
只要子查询不是相关子查询,聚合和 GROUP BY 子句即可在这些子查询中使用。
-
ALL
和[NOT] IN
下的相关表达式不受支持。 -
OR
下的相关表达式不受支持。 -
对于使用等式 (=) 谓词联接的子查询,才仅允许使用多重相关。但是,不允许在相关子查询中使用
IN
/NOT IN
、EXISTS
/NOT EXISTS
谓词:=> SELECT t2.x, t2.y, t2.z FROM t2 WHERE t2.z NOT IN (SELECT t1.z FROM t1 WHERE t1.x = t2.x); ERROR: Correlated subquery with NOT IN is not supported
-
如果子查询引用了当前外部查询块中的列,则
WHERE
子句中最多只能使用一个级别的相关子查询。例如,以下查询不受支持,因为t2.x = t3.x
子查询只能在外部查询中引用表t1
,使其成为相关表达式,因为t3.x
具有两个以上的级别:=> SELECT t3.x, t3.y, t3.z FROM t3 WHERE t3.z IN ( SELECT t1.z FROM t1 WHERE EXISTS ( SELECT 'x' FROM t2 WHERE t2.x = t3.x) AND t1.x = t3.x); ERROR: More than one level correlated subqueries are not supported
如果按如下所示进行重写,则支持该查询:
=> SELECT t3.x, t3.y, t3.z FROM t3 WHERE t3.z IN (SELECT t1.z FROM t1 WHERE EXISTS (SELECT 'x' FROM t2 WHERE t2.x = t1.x) AND t1.x = t3.x);