2015-04-29 30 views
5

JSON数组给定一个表,其中包含JSON的这样一列:如何跨越加入UNNEST在急

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

我如何写一个普雷斯托查询给我所有的平均b值项?

到目前为止,我认为我需要使用像Hive的lateral view explode,其在Presto中相当于cross join unnest

但我被困在如何编写cross join unnest的Presto查询。

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

回答

3

加正如你指出的那样,这是终于在普雷斯托0.79实施。 :)

这里是here的语法投的一个例子:

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

建议的特殊字,存在不普雷斯托“字符串”型像有在蜂巢。 这意味着如果你的数组包含字符串,请确保使用'varchar'类型,否则你会得到一个错误消息,说'类型数组不存在',这可能会引起误解。

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

值不能被转换为数组(varchar) – colintobing

0

下面是该

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一个例子定义了别名为message

VALUES返回逐字表行集

列公用表表达式(CTE)名称exampleUNNEST正在单行和returni的列中取数组将数组的元素分成多行。

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

JSON_EXTRACT使用jsonPath表达式返回​​键

avg()group by应该熟悉SQL的数组值。

+0

该问题指定了Presto,但是如果使用Athena,它似乎将转换为'ARRAY(ROW('和其他一些复杂类型不被支持,所以使用'ARRAY(MAP(VARCHAR ,VARCHAR))'而不是在select和group by子句中引用诸如'xn ['type']'等的值 – Davos