Я работаю на стандартном диалекте BigQuery SQL.
У меня есть столбец, который, как я знаю, является массивом словарей JSON.
Длина массива варьируется от строки к строке.
Я бы хотел сгладить это, чтобы иметь доступ к элементам JSON для каждого словаря в массивах.
Например, допустим, у меня есть две записи. Первый имеет id
из 1, а в столбце JSON этот
[
{"key1":"val1a", "key2": "val1b"},
{"key1":"val1c", "key2": "val1d"}
]
Второй имеет id
из 2, а в столбце JSON -
[{"key1":"val2a", "key2":"val2b"}]
Моя цель
id | key1 | key2 | offset
---------------------------
1 | val1a | val1b | 1
1 | val1c | val1d | 2
2 | val2a | val2b | 1
(хотя я мог бы жить без смещенного столбца)
Кажется, что-то подобное может сработать ...
WITH table AS (
SELECT 1 as id,['{"key1":"val1a", "key2": "val1b"}','{"key1":"val1c", "key2": "val1d"}'] as array_column
UNION ALL
SELECT 2 as id,['{"key1":"val2a", "key2":"val2b"}'] as array_column)
SELECT id,
json_extract_scalar(flattened_array, '$.key1') as key1,
json_extract_scalar(flattened_array, '$.key2') as key2
FROM table t
CROSS JOIN UNNEST(t.array_column) AS flattened_array
И фактически, этот запрос возвращает ожидаемую таблицу (за исключением столбца смещения, который тривиально добавить)
Проблема в том, что BigQuery не понимает, что это массив JSON-подобных строк. Он думает, что все это одна большая нить, и я не знаю, как убедить это иначе. Редактирование моего примера для симуляции этого смешения типов демонстрирует проблему:
WITH table AS (
SELECT 1 as id,'[{"key1":"val1a", "key2": "val1b"},{"key1":"val1c", "key2": "val1d"}]' as array_column
UNION ALL
SELECT 2 as id,'[{"key1":"val2a", "key2":"val2b"}]' as array_column)
SELECT id,
json_extract_scalar(flattened_array, '$.key1') as key1,
json_extract_scalar(flattened_array, '$.key2') as key2
FROM table t
CROSS JOIN UNNEST(t.array_column) AS flattened_array
Здесь валидатор жалуется, потому что Значения, указанные в UNNEST, должны быть массивами. UNNEST содержит выражение типа STRING в [29:23]
И теперь мы в центре этой проблемы. Есть ли какой-то очевидный способ заставить BigQuery понять, что эта строка является допустимым массивом словарей JSON? Может быть, какая-то JSON_*
функция, которую я пропустил, сгладит массив? Или каким-то образом CAST
эта вещь в массиве?