如何使用“ as”子句修复“必须为聚合表达式或出现在GROUP BY子句中”

时间:2019-05-31 07:54:49

标签: sql group-by presto amazon-athena

我正在尝试使用athena查询按小时获取CloudFront分发的请求数。

我在sample_db中由this Link指导创建了cloudfront_logs表

下面是我要按小时获取请求数的查询

SELECT date_trunc('hour',from_iso8601_timestamp(concat(concat(date_format(date, '%Y-%m-%d'), 'T'), time))) as TIME, count(*) as CNT
FROM "sample_db"."cloudfront_logs" 
WHERE 
    from_iso8601_timestamp(concat(concat(date_format(date, '%Y-%m-%d'), 'T'), time)) >= from_iso8601_timestamp('2019-05-29T00:00:00')
AND 
    from_iso8601_timestamp(concat(concat(date_format(date, '%Y-%m-%d'), 'T'), time)) < from_iso8601_timestamp('2019-05-30T00:00:00')
GROUP BY TIME
ORDER BY TIME ASC;

但是它会返回这样的错误

SYNTAX_ERROR: line 2:8: '"date_trunc"('hour', "from_iso8601_timestamp"("concat"("concat"("date_format"("date", '%Y-%m-%d'), 'T'), "time")))' must be an aggregate expression or appear in GROUP BY clause

因此,我将TIME之后的GROUP BY替换为date_trunc('hour',from_iso8601_timestamp(concat(concat(date_format(date, '%Y-%m-%d'), 'T'), time))),然后再次尝试。

SELECT date_trunc('hour',from_iso8601_timestamp(concat(concat(date_format(date, '%Y-%m-%d'), 'T'), time))) as TIME, count(*) as CNT
FROM "sample_db"."cloudfront_logs" 
WHERE 
    from_iso8601_timestamp(concat(concat(date_format(date, '%Y-%m-%d'), 'T'), time)) >= from_iso8601_timestamp('2019-05-29T00:00:00')
AND 
    from_iso8601_timestamp(concat(concat(date_format(date, '%Y-%m-%d'), 'T'), time)) < from_iso8601_timestamp('2019-05-30T00:00:00')
GROUP BY date_trunc('hour',from_iso8601_timestamp(concat(concat(date_format(date, '%Y-%m-%d'), 'T'), time)))
ORDER BY TIME ASC;

最后,我得到了结果。

我认为,它也应该与第一个查询一起使用。我可以在第一个查询中获得任何建议吗?因为它看起来更简单。

2 个答案:

答案 0 :(得分:1)

这似乎是Athena SQL没有在同一级别的SELECT子句中的GROUP BY子句中使用别名。但是,许多版本的SQL都允许这样做。您可以尝试在此处使用CTE来使事情变得不太冗长:

WITH cte AS (
    SELECT from_iso8601_timestamp(concat(concat(date_format(date, '%Y-%m-%d'), 'T'), time)) AS ts
    FROM "sample_db"."cloudfront_logs"
)

SELECT
    DATE_TRUNC('hour', ts) AS TIME,
    COUNT(*) AS CNT
FROM cte
WHERE
    ts >= from_iso8601_timestamp('2019-05-29T00:00:00') AND
    ts <  from_iso8601_timestamp('2019-05-30T00:00:00')
GROUP BY
    DATE_TRUNC('hour', ts)
ORDER BY
    DATE_TRUNC('hour', ts);

答案 1 :(得分:1)

雅典娜基于Presto。在Presto中,不能在SELECT子句中使用GROUP BY子句列别名。 但是,您可以使用相同的表达式,例如:

SELECT some_expression(a) FROM ... GROUP BY some_expression(a)

此外,您可以使用它们在SELECT列表中的位置来引用SELECT子句列:

SELECT some_expression(a) FROM ... GROUP BY 1

这是ANSI SQL标准语法。有关模式的详细信息,请参见Presto GROUP BY documentation

这也可以在ORDER BY中使用,因此您的查询将类似于

SELECT date_trunc('hour',from_iso8601_timestamp(concat(concat(date_format(date, '%Y-%m-%d'), 'T'), time))) as TIME, count(*) as CNT
FROM "sample_db"."cloudfront_logs" 
WHERE ...
GROUP BY 1
ORDER BY 1 ASC;