Presto unnest json
Posted
技术标签:
【中文标题】Presto unnest json【英文标题】: 【发布时间】:2016-04-02 11:55:44 【问题描述】:关注这个问题:how to cross join unnest a json array in presto
我尝试运行提供的示例,但是 我这样做时出错了
SQL 命令:
select x.n
from
unnest(cast(json_extract('"payload":["type":"b","value":"9",
"type":"a","value":"8"]','$.payload') as array<varchar>)) as x(n)
我得到的错误:
Value cannot be cast to array<varchar>
java.lang.RuntimeException: java.lang.NullPointerException: string is null
【问题讨论】:
【参考方案1】:SELECT JSON_EXTRACT('"payload":["type":"b","value":"9", "type":"a","value":"8"]','$.payload')
给予:
["type":"b","value":"9", "type":"a","value":"8"]
这是ARRAY<MAP<VARCHAR,VARCHAR>>
。
您可以将查询更改为:
SELECT x.n
FROM
UNNEST (CAST(JSON_EXTRACT('"payload":["type":"b","value":"9","type":"a","value":"8"]','$.payload') AS ARRAY<MAP<VARCHAR, VARCHAR>>)) AS x(n)
【讨论】:
我运行了你的建议,它似乎部分有效。为了分离地图的值,我必须明确选择地图的值:`SELECT xn['type']as "type",xn['value']as "value" FROM UNNEST (CAST(JSON_EXTRACT(' "有效载荷":["type":"b","value":"9","type":"a","value":"8"]','$.payload') AS ARRAY 另一种选择,您可以像这样使用 x(type,value) ::: SELECT type, value FROM UNNEST(CAST(JSON_EXTRACT( '"payload":[ "type":"b","value":"9","type":"a","value":"8"]' ,'$.payload' ) as ARRAY(ROW( type VARCHAR, value VARCHAR)) ) ) as x(type,value);【参考方案2】:返回数据类型的一种可能解释如下:
ARRAY<MAP<VARCHAR,VARCHAR>>
但缺点是无法使用点表示法访问地图中的值。
另一种假设的数据类型是:
ARRAY(ROW(type VARCHAR, value VARCHAR))
类似于 ARRAY<STRUCT<
Hive 数据类型等效项。
这里有很多题外话>> JSON 有点模棱两可。
哪一个是正确的? JSON 对象是映射的表示(哈希图、字典、键值对,无论您的语言如何称呼它)还是更像一个结构(对象、类、名称属性包,无论您的语言如何称呼)?它起源于 javascript(对象表示法),旨在满足数组、对象和原始类型的需求,但更广泛的使用意味着它在其他语言中具有模棱两可的映射 (ha)。也许在功能上等效,但理论上MAP
对于随机读/写应该更快,ROW
可能有一些额外的面向对象的开销,但这都是在 Java 中实现的,反正一切都是对象,所以我没有答案。使用任何你喜欢的东西。
您发现这有点冗长:
SELECT
x.n['type'] as "type",
x.n['value'] as "value"
FROM UNNEST (
CAST(
JSON_EXTRACT('"payload":["type":"b","value":"9","type":"a","value":"8"]'
,'$.payload')
AS ARRAY<MAP<VARCHAR, VARCHAR>>
)
)
AS x(n)
这是另一种选择
SELECT
n.type,
n.value
FROM UNNEST(
CAST(
JSON_EXTRACT(
'"payload":["type":"b","value":"9","type":"a","value":"8"]'
,'$.payload'
)
as ARRAY(ROW(type VARCHAR, value VARCHAR))
)
) as x(n)
同样冗长;列的名称只是转移到 CAST 表达式,但可能(主观!)更容易查看。
【讨论】:
【参考方案3】:您可以对各个列使用 JSON_EXTRACT、CAST 和最后的 UNNEST
SELECT type,value FROM
UNNEST(CAST(JSON_EXTRACT('"payload":["type":"b","value":"9",
"type":"a","value":"8"]'
,'$.payload'
) as ARRAY(ROW(type VARCHAR, value VARCHAR)
)
)
) as x(type,value)
输出如下
type | value
------+-------
b | 9
a | 8
【讨论】:
以上是关于Presto unnest json的主要内容,如果未能解决你的问题,请参考以下文章