在 presto/athena 中按元素聚合数组
Aggregate arrays element-wise in presto/athena
我有一个 table,它有一个 array
列。保证数组的大小在所有行中都相同。是否可以对数组进行逐元素聚合以创建新数组?
例如如果我的聚合是 avg
函数,那么:
Array 1: [1,3,4,5]
Array 2: [3,5,6,1]
Output: [2,4,5,3]
我想写这样的查询:
select
timestamp_column,
avg(array_column) as new_array
from
my_table
group by
timestamp_column
该数组包含将近 200 个元素,因此我不希望对查询中的每个元素进行硬编码 :)
这可以通过组合 2 个鲜为人知的 SQL 构造来完成:UNNEST WITH ORDINALITY,以及 array_agg 和 ORDER BY。
第一步是使用CROSS JOIN UNNEST(a) WITH ORDINALITY
将数组解压成行。对于每个数组中的每个元素,它将输出一行,其中包含元素值和该元素在数组中的位置。
然后在序数上使用标准 GROUP BY
,在值上使用 sum
。
最后,您使用 array_agg(value_sum ORDER BY ordinal)
将总和重新组装回数组。此表达式的关键部分是 array_agg
调用中的 ORDER BY
子句。没有这个,值将是任意顺序。
这是一个完整的例子:
WITH t(a) AS (VALUES array [1, 3, 4, 5], array [3, 5, 6, 1])
SELECT array_agg(value_sum ORDER BY ordinal)
FROM (
SELECT ordinal, sum(value) AS value_sum
from t
CROSS JOIN UNNEST(t.a) WITH ORDINALITY AS x(value, ordinal)
GROUP BY ordinal);
我有一个 table,它有一个 array
列。保证数组的大小在所有行中都相同。是否可以对数组进行逐元素聚合以创建新数组?
例如如果我的聚合是 avg
函数,那么:
Array 1: [1,3,4,5]
Array 2: [3,5,6,1]
Output: [2,4,5,3]
我想写这样的查询:
select
timestamp_column,
avg(array_column) as new_array
from
my_table
group by
timestamp_column
该数组包含将近 200 个元素,因此我不希望对查询中的每个元素进行硬编码 :)
这可以通过组合 2 个鲜为人知的 SQL 构造来完成:UNNEST WITH ORDINALITY,以及 array_agg 和 ORDER BY。
第一步是使用CROSS JOIN UNNEST(a) WITH ORDINALITY
将数组解压成行。对于每个数组中的每个元素,它将输出一行,其中包含元素值和该元素在数组中的位置。
然后在序数上使用标准 GROUP BY
,在值上使用 sum
。
最后,您使用 array_agg(value_sum ORDER BY ordinal)
将总和重新组装回数组。此表达式的关键部分是 array_agg
调用中的 ORDER BY
子句。没有这个,值将是任意顺序。
这是一个完整的例子:
WITH t(a) AS (VALUES array [1, 3, 4, 5], array [3, 5, 6, 1])
SELECT array_agg(value_sum ORDER BY ordinal)
FROM (
SELECT ordinal, sum(value) AS value_sum
from t
CROSS JOIN UNNEST(t.a) WITH ORDINALITY AS x(value, ordinal)
GROUP BY ordinal);