簡體   English   中英

在 AWS Athena / Presto 中 unnest 和 array_agg 后保留數組元素的順序

[英]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
  1. 默認行為似乎是保留順序。 它可靠嗎?
  2. 如果不是(1),是否有一種實現可以保留bsys的順序?

有同樣的問題,我的解決方法是聚合值以將序數作為鍵進行映射。 然后將映射的值轉換為數組(按鍵排序):

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

  1. 使用排序字符串作為每個輸出值的前綴
  2. 聚合到未排序的數組中
  3. 對數組進行排序
  4. 從每個數組元素中刪除排序前綴
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

該方法假設:

  • 可排序的數據將適合 varchar 數組列
  • b是字符數據(或易於轉換)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM