![](/img/trans.png)
[英]athena array_agg sort by multiple values results in incorrect order
[英]Preserve order of array elements after unnest and array_agg in AWS Athena / Presto
我有一个 Athena 查询,它取消嵌套一个数组,将元素与另一个表连接起来,然后使用array_agg
将它们收集回一个数组中。 我想保留元素的原始顺序,但 Athena 不支持 Presto 功能向array_agg
添加ORDER BY
子句。 如何保留元素的顺序?
查询类似于此示例:
SELECT x, array_agg(b) bs
FROM table1 -- table1 columns are x, ys
CROSS JOIN UNNEST(ys) AS t(y)
JOIN table2 ON y=a -- table2 columns are a, b
GROUP BY x
bs
中ys
的顺序?有同样的问题,我的解决方法是聚合值以将序数作为键进行映射。 然后将映射的值转换为数组(按键排序):
SELECT t1.x,
transform(sequence(1,cardinality(map_agg(n,y)),(x)-> map_agg(n,y)[x])
FROM table1 t1 CROSS JOIN
UNNEST(t1.ys) WITH ORDINALITY AS t(y, n) JOIN
table2 t2
ON t1.y = t2.a
GROUP BY t1.x;
Presto 支持with ordinality
unnest()
:
SELECT t1.x, array_agg(t2.b ORDER BY n) bs
FROM table1 t1 CROSS JOIN
UNNEST(t1.ys) WITH ORDINALITY AS t(y, n) JOIN
table2 t2
ON t1.y = t2.a
GROUP BY t1.x;
请注意,您不需要注释来指定列的来源。 只需使用适当的表别名质量列引用。 这也使查询明确且易于理解。
一种在没有ORDER BY
情况下保留ORDER BY
:
SELECT
x
-- prefix each "b" with a 19-digit sortable string
-- aggregate into array, sort, then remove the prefix
, TRANSFORM(
ARRAY_SORT(
array_agg(
SUBSTR(LPAD(CAST(yi AS VARCHAR), 19, '0'), -19)
|| b))
, e1 -> SUBSTR(e1, 1 + 19)
) AS bs
FROM table1 -- table1 columns are x, ys
CROSS JOIN UNNEST(ys) WITH ORDINALITY t (y, yi)
JOIN table2 ON y = a -- table2 columns are a, b
GROUP BY x
该方法假设:
b
是字符数据(或易于转换)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.