Presto unnest json

после этого вопроса: как перекрестно объединить массив 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


person Lior Baber    schedule 28.12.2015    source источник


Ответы (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)

person Shusen Liu    schedule 04.03.2016
comment
Я провожу ваше предложение, и оно, похоже, частично работает. чтобы разделить значение карты, мне пришлось явно выбрать значения карты: `SELECT xn ['type'] как тип, xn ['value'] как значение FROM UNNEST (CAST (JSON_EXTRACT ('{payload: [{ type: b, value: 9}, {type: a, value: 8}]} ',' $. payload ') AS ARRAY ‹MAP‹ VARCHAR, VARCHAR ››)) AS x (n) `есть ли альтернативный прямой подход? - person Lior Baber; 06.03.2016
comment
Другой альтернативой является использование x (тип, значение) следующим образом ::: SELECT тип, значение FROM UNNEST (CAST (JSON_EXTRACT ('{payload: [{type: b, value: 9}, {type: a, value: 8}]} ',' $. payload ') как ARRAY (ROW (тип VARCHAR, значение VARCHAR)))) как x (тип, значение); - person meril; 10.02.2019

Одна из возможных интерпретаций возвращаемого типа данных следующая:

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, но возможно (субъективно!) легче смотреть.

person Davos    schedule 06.03.2018

Вы можете использовать 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
person meril    schedule 10.02.2019