7

跟随这个问题:如何在 presto 中交叉加入 unnest json 数组

我尝试运行提供的示例,但这样做时出现错误

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

4

3 回答 3

5

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)

于 2016-03-04T19:33:42.603 回答
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
于 2019-02-10T18:24:23.670 回答
3

返回数据类型的一种可能解释如下:

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 表达式,但可能(主观!)更容易查看。

于 2018-03-06T04:33:33.890 回答