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

Bum*_*Kim 4 sql group-by presto amazon-athena

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

我在我的sample_db中创建了由此链接引导的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;
Run Code Online (Sandbox Code Playgroud)

但是它返回这样的错误

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
Run Code Online (Sandbox Code Playgroud)

因此,我将TIMEafter替换GROUP BYdate_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;
Run Code Online (Sandbox Code Playgroud)

最后,我得到了结果。

我认为,它也应该适用于第一个查询。我可以就第一个查询得到任何建议吗?因为它看起来更简单。

Pio*_*sen 6

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

SELECT some_expression(a) FROM ... GROUP BY some_expression(a)
Run Code Online (Sandbox Code Playgroud)

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

SELECT some_expression(a) FROM ... GROUP BY 1
Run Code Online (Sandbox Code Playgroud)

这是 ANSI SQL 标准语法。有关模式详细信息,请参阅Presto GROUP BY 文档

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;
Run Code Online (Sandbox Code Playgroud)