【问题标题】:Add two maps in Presto在 Presto 中添加两个地图
【发布时间】:2019-02-02 01:38:17
【问题描述】:

我的数据如下所述

customer_id   usage_month  usage_by_product         usage
1             June         {"A":50, "B":50}         100
1             July         {"A":50, "B":10, "C":20} 80
1             Aug          {"A":50, "D":500}        550
1             Sep          {"C" :30}                30

我想编写一个汇总全年总使用量的查询

customer_id   usage_by_product    usage
 1            {"A": 150, "B":60   760
               "C": 50, "D":500}

是否可以在 Athena (Presto) 中的地图上进行这种聚合?

【问题讨论】:

    标签: presto


    【解决方案1】:

    您可以使用map_entries + UNNEST 将地图拆分为单独的键/值对。然后,将值求和并聚合回map

    例如:

    WITH input AS (
        SELECT * FROM (VALUES
            (1, map(array['a', 'c'], array[50, 42])), 
            (1, map(array['a', 'b'], array[50, 18]))
        ) t(customer_id, m)
    ),
    sum_by_map_key AS (
        SELECT customer_id, k, sum(v) AS s
        FROM input
        CROSS JOIN UNNEST(map_entries(m)) AS u(k, v)
        GROUP BY customer_id, k
    )
    SELECT customer_id, map_agg(k, s)
    FROM sum_by_map_key
    GROUP BY customer_id;
    

    输出:

     customer_id |        _col1
    -------------+---------------------
               1 | {a=100, b=18, c=42}
    (1 row)
    

    注意: 要像这样添加两张地图,您可以使用map_zip_with。但是,要在聚合多行时使用它,您可能需要将所有映射值聚合到单个 array 并在其上运行数组缩减。根据这些数组的大小,将所有地图聚合到单个 array(map) 中可能有效,也可能无效。

    【讨论】:

    • 感谢您的解释。我确实探索了map_zip_with,在文档“通过将函数应用于具有相同键的一对值来将两个给定的映射合并到一个映射中。对于仅在一个映射中出现的键,NULL 将作为缺少键的值传递."。因此,当我尝试添加值时,它会将 null 添加到 int 值,而两个映射中都不存在相同的键?
    • 令我惊讶的是,雅典娜有一个旧版本的 Presto (0.172),它不支持 map_with_zip、ma​​p_entries 和 map_agg。
    • 对于map_zip_with,您将使用coalesce(v1, 0) + coalesce(v2, 0) 对值求和以正确处理丢失的键。我不知道 Athena 中不存在这些功能。 0.172 已经很老了。除非您很少查询(即当 Athena 成本模型效果最佳时),否则我建议您使用 starburstdata.com/presto-aws-cloud 或 EMR。
    猜你喜欢
    • 2019-06-15
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多