子查询限制

以下限制适用于 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] INANY 子查询(嵌套在另一个表达式中)在以下情况下不受支持:任一列值为 NULL。例如,在以下语句中,如果表 t1t2 中的列 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 INEXISTS/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);