如何在Presto中交叉连接不需要的JSON数组

时间:2015-04-29 01:46:18

标签: json hadoop hive presto

给定一个包含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扩展所有数组元素并选择它们?

3 个答案:

答案 0 :(得分:4)

这是

的一个例子
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类型更改为ARRAY所需的UNNEST类型。它可以很容易地成为ARRAY<MAP<,但我发现ARRAY(ROW(更好,因为您可以指定列名称,并在select子句中使用点表示法。

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

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

答案 1 :(得分:3)

正如您所指出的,这最终在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>);

答案 2 :(得分:1)