13

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

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

如何编写 Presto 查询以提供b所有条目的平均值?

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

但我坚持如何编写 Presto 查询cross join unnest

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

4

3 回答 3

14

这是一个例子

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定义了一个公用表表达式 (CTE),其名称example以列别名为message

VALUES返回逐字表行集

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

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

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

avg()并且group by应该熟悉SQL。

于 2018-03-06T04:51:20.523 回答
5

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

以下是来自此处的演员表的语法示例:

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>);
于 2015-09-07T08:27:59.773 回答
2

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

unnest在 0.79 版本中添加

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

于 2015-04-30T22:43:20.227 回答