【问题标题】:Preserve order of array elements after unnest and array_agg in AWS Athena / Presto在 AWS Athena / Presto 中的 unnest 和 array_agg 之后保留数组元素的顺序
【发布时间】:2019-12-16 21:10:23
【问题描述】:

我有一个 Athena 查询,它取消了一个数组的嵌套,将元素与另一个表连接起来,然后使用 array_agg 将它们收集回一个数组中。我想保留元素的原始顺序,但 Athena 不支持 Presto 功能在ORDER BY 中添加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),是否有一个实现可以保留 ysbs 中的顺序?

【问题讨论】:

    标签: sql presto amazon-athena


    【解决方案1】:

    有同样的问题,我的解决方法是聚合值以映射以序数为键。然后将映射的值转换为数组(按键排序):

    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;
    

    【讨论】:

      【解决方案2】:

      Presto 支持unnest() with ordinality:

      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;
      

      请注意,您不需要 cmets 来指定列的来源。只需使用适当的表别名来质量列引用。这也使查询明确且更易于理解。

      【讨论】:

      • PrestoDB 支持带有 OREDER BY 的 array_agg,但遗憾的是,不是 100% presto 的 Athena 不支持 :(
      • @LittleBobbyTables 。 . .好吧,它至少应该适用于 PrestoDB。可能没有办法在 Athena 上做你想做的事。
      • @LittleBobbyTables Athena 可能总是落后于最新的 Presto。但对于新读者,我可以确认它现在受支持并且可以正常工作。
      【解决方案3】:

      在没有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 是字符数据(或易于转换)

      【讨论】:

        猜你喜欢
        • 2020-11-02
        • 2021-06-20
        • 1970-01-01
        • 2020-12-24
        • 2020-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多