如何在 Presto 中交叉加入取消嵌套 JSON 数组

Posted

技术标签:

【中文标题】如何在 Presto 中交叉加入取消嵌套 JSON 数组【英文标题】:How to cross join unnest a JSON array in Presto 【发布时间】: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 展开所有数组元素并选中它们?

【问题讨论】:

【参考方案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】:

问题是我运行的是旧版本的 Presto。

unnest 在 0.79 版本中添加

https://github.com/facebook/presto/blob/50081273a9e8c4d7b9d851425211c71bfaf8a34e/presto-docs/src/main/sphinx/release/release-0.79.rst

【讨论】:

以上是关于如何在 Presto 中交叉加入取消嵌套 JSON 数组的主要内容,如果未能解决你的问题,请参考以下文章

将 JSON 取消嵌套到 SQL 行

如何使用python取消嵌套json格式的数据

如何在redshift上取消嵌套json字符串数组[重复]

如何取消嵌套不规则的 JSON 数据

取消嵌套嵌套 json 数据以显示在 Quicksight 中

在 Presto 中进行基于范围的交叉连接的最佳方法是啥?