【问题标题】:How to cross join unnest a JSON array in Presto如何在 Presto 中交叉加入取消嵌套 JSON 数组
【发布时间】:2015-07-08 02:27:33
【问题描述】:

给定一个包含如下 JSON 列的表:

{"payload":[{"type":"b","value":"9"}, {"type":"a","value":"8"}]}
{"payload":[{"type":"c","value":"7"}, {"type":"b","value":"3"}]}

如何编写一个 Presto 查询来为我提供所有条目的平均 b 值?

到目前为止,我认为我需要使用 Hive 的 lateral view explode 之类的东西,它的等价物是 Presto 中的 cross join unnest。

但我不知道如何为 cross join unnest 编写 Presto 查询。

如何使用cross join unnest 展开所有数组元素并选中它们?

【问题讨论】:

    标签: json hadoop hive presto


    【解决方案1】:

    这是一个例子

    with example(message) as (
    VALUES
    (json '{"payload":[{"type":"b","value":"9"},{"type":"a","value":"8"}]}'),
    (json '{"payload":[{"type":"c","value":"7"}, {"type":"b","value":"3"}]}')
    )
    
    
    SELECT
            n.type,
            avg(n.value)
    FROM example
    CROSS JOIN
        UNNEST(
                CAST(
                    JSON_EXTRACT(message,'$.payload')
                        as ARRAY(ROW(type VARCHAR, value INTEGER))
                        )
                    ) as x(n)
    WHERE n.type = 'b'
    GROUP BY n.type
    

    with 定义了一个名为 example 的公用表表达式 (CTE),其列别名为 message

    VALUES 返回逐字表行集

    UNNEST 在单行的列中获取一个数组,并将该数组的元素作为多行返回。

    CAST 正在将JSON 类型更改为UNNEST 所需的ARRAY 类型。它可能很容易成为 ARRAY<MAP<,但我发现 ARRAY(ROW( 更好,因为您可以指定列名,并在 select 子句中使用点表示法。

    JSON_EXTRACT 正在使用 jsonPath 表达式返回 payload 键的数组值

    avg() 和group by 应该是熟悉的 SQL。

    【讨论】:

    • 问题指定了 Presto,但是如果使用 Athena,它似乎转换为 ARRAY(ROW( 并且不支持其他一些复杂类型,因此请改用 ARRAY(MAP(VARCHAR,VARCHAR)) 并在 select 和 group by 子句中参考x.n['type'] 等值
    【解决方案2】:

    正如您所指出的,这最终在 Presto 0.79 中实现。 :)

    下面是here 的转换语法示例:

    select cast(cast ('[1,2,3]' as json) as array<bigint>);
    

    特别忠告,Presto 中没有像 Hive 中那样的“字符串”类型。 这意味着如果您的数组包含字符串,请确保您使用类型“varchar”,否则您会收到一条错误消息,提示“类型数组不存在”,这可能会产生误导。

    select cast(cast ('["1","2","3"]' as json) as array<varchar>);
    

    【讨论】:

    • 值不能转换为数组(varchar)
    【解决方案3】:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-07
      • 2020-04-18
      • 2021-07-28
      • 2020-01-08
      • 1970-01-01
      • 2021-06-01
      • 1970-01-01
      • 2021-12-15
      相关资源
      最近更新 更多