【问题标题】:Presto unnest jsonPresto 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

【问题讨论】:

    标签: json hadoop hive presto


    【解决方案1】:

    SELECT JSON_EXTRACT('{"payload":[{"type":"b","value":"9"}, {"type":"a","value":"8"}]}','$.payload')

    给予:

    [{"type":"b","value":"9"}, {"type":"a","value":"8"}]

    这是ARRAY&lt;MAP&lt;VARCHAR,VARCHAR&gt;&gt;。 您可以将查询更改为: 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>)) AS x(n)` 是否有替代的直接方法?
    • 另一种选择,您可以像这样使用 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&lt;STRUCT&lt; 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
      

      【讨论】:

        猜你喜欢
        • 2021-07-10
        • 2020-11-02
        • 1970-01-01
        • 2020-10-21
        • 1970-01-01
        • 2019-01-21
        • 2020-04-21
        • 1970-01-01
        • 2020-12-24
        相关资源
        最近更新 更多