Vertica的。在子查询和外部查询分组

时间:2018-02-19 15:32:09

标签: sql group-by vertica

我尝试执行以下查询,但收到错误:

SELECT * FROM (
  SELECT
    DATEDIFF('year', event_timestamp, NOW())
  FROM 
    events
  GROUP BY CUBE(
    DATEDIFF('year', event_timestamp, NOW())
  )
  HAVING GROUPING(
    DATEDIFF('year', event_timestamp, NOW())
  ) = 0
) AS subqueries GROUP BY 1;

查询看起来很奇怪,因为它只是MCVE。真实查询由外部查询中的分组下的多个子查询组成,并且在HAVING子句中具有更复杂的条件。

  

[42803] [7182] [Vertica] VJDBC错误:分组函数参数需要按表达式分组

但正如您所看到的,GROUPING()参数与CUBE()SELECT子句相同。

如果NOW()函数被某个固定值替换,那么查询效果很好:

SELECT * FROM (
  SELECT
    DATEDIFF('year', event_timestamp, '2018-01-01 00:00:00')
  FROM 
    events
  GROUP BY CUBE(
    DATEDIFF('year', event_timestamp, '2018-01-01 00:00:00')
  )
  HAVING GROUPING(
    DATEDIFF('year', event_timestamp, '2018-01-01 00:00:00')
  ) = 0
) AS subqueries GROUP BY 1;
-- ok

是否禁止使用NOW(),因为它可以为查询执行的不同部分返回不同的值(即实际处理GROUP BYHAVING时)?
如果这是真的,那么无论使用NOW() ,为什么基本查询的以下修改也能使其工作:

只有外部查询之外的未经修改的子查询:

SELECT
  DATEDIFF('year', event_timestamp, NOW())
FROM 
  events
GROUP BY CUBE(
  DATEDIFF('year', event_timestamp, NOW())
)
HAVING GROUPING(
  DATEDIFF('year', event_timestamp, NOW())
) = 0
-- ok

没有GROUP BY子句的外部查询:

SELECT * FROM (
  SELECT
    DATEDIFF('year', event_timestamp, NOW())
  FROM 
    events
  GROUP BY CUBE(
    DATEDIFF('year', event_timestamp, NOW())
  )
  HAVING GROUPING(
    DATEDIFF('year', event_timestamp, NOW())
  ) = 0
) AS subqueries;
-- ok

我可以通过在应用程序端获取当前时间来解决问题,但我只是想了解这个问题。我是否会错过一些关于SQL的基础知识,或者它是Vertica的边缘案例?

Vertica版本:8.1

更新2018-07-04:此错误已在Vertica 8.1.1-20中修复(请参阅this comment)。

1 个答案:

答案 0 :(得分:2)

您可以尝试:

SELECT * FROM (
  SELECT 
    DATEDIFF('year', event_timestamp, (select now()))
  FROM 
    events
  GROUP BY CUBE(
    DATEDIFF('year', event_timestamp, (select now()))
  )
  HAVING GROUPING(
    DATEDIFF('year', event_timestamp, (select now()))
  ) = 0
) AS subqueries GROUP BY 1;

NOW()被认为是一个STABLE函数:它将在同一事务中的后续调用中返回完全相同的值。

<强>更新

在大多数情况下,此解决方法很好,但在某些情况下会导致Vertica的内部错误。 请参阅Vertica论坛的相关讨论:https://forum.vertica.com/discussion/239469/