关注这个问题: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
答案 0 :(得分:3)
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)
答案 1 :(得分:1)
返回数据类型的一种可能解释如下:
ARRAY<MAP<VARCHAR,VARCHAR>>
但缺点是无法使用点表示法访问地图中的值。
要假设的另一种数据类型是:
ARRAY(ROW(type VARCHAR, value VARCHAR))
类似于ARRAY<STRUCT<
Hive数据类型等效。
大量离题&gt;&gt; JSON有点含糊不清。
哪一个是正确的? JSON对象是地图的表示(散列映射,字典,键值对,无论您的语言是什么),还是更像是一个结构(对象,类,名称属性包,无论您的语言是什么)?它起源于旨在满足数组,对象和原始类型的JavaScript(对象表示法),但更广泛的使用意味着它在其他语言中具有模糊映射(ha)。也许在功能上等同,但理论上MAP
对于随机读/写应该更快,ROW
可能有一些额外的面向对象的开销,但这都是在Java中实现的,其中一切都是对象,所以我没有答案。用你喜欢的任何东西。的&LT;&LT;我离题了。
你发现这有点冗长:
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表达式,但也许(主观!)更容易看。
答案 2 :(得分:0)
您可以使用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