Как преобразовать строковый массив в массив в BigQuery?
Так получилось, у меня есть строковый массив в поле в BigQuery
'["a","b","c"]'
и я хочу преобразовать его в массив, который понимает BigQuery. Я хочу быть в состоянии сделать это в стандартном SQL:
with k as (select '["a","b","c"]' as x)
select x from k, unnest(x) x
я пытался JSON_EXTRACT('["a","b","c"]','$')
и все остальное, что я мог найти в Интернете.
Есть идеи?
1 ответ
Ниже для BigQuery Standard SQL
#standardSQL
WITH k AS (
SELECT 1 AS id, '["a","b","c"]' AS x UNION ALL
SELECT 2, '["x","y"]'
)
SELECT
id,
ARRAY(SELECT * FROM UNNEST(SPLIT(SUBSTR(x, 2 , LENGTH(x) - 2)))) AS x
FROM k
Он превращает ваш строковый столбец в столбец массива
Недавно (2020 г.)
JSON_EXTRACT_ARRAY
функция была добавлена в стандартный sql.
Это позволяет легко получить ожидаемое поведение без UDF или уловок
with k as (select JSON_EXTRACT_ARRAY('["a","b","c"]', '$') as x)
select unnested_x from k, unnest(x) unnested_x
Результатом будет:
╔══════════════╗
║ "unnested_x" ║
╠══════════════╣
║ "a" ║
║ "b" ║
║ "c" ║
╚══════════════╝
Это решение обновляет ответ @northtree и более элегантно обрабатывает возврат членов массива в виде строковых объектов JSON, а не возврат [object Object]
струны:
CREATE TEMP FUNCTION
JSON_EXTRACT_ARRAY(input STRING)
RETURNS ARRAY<STRING>
LANGUAGE js AS """
return JSON.parse(input).map(x => JSON.stringify(x));
""";
with
raw as (
select
1 as id,
'[{"a": 5, "b": 6}, {"a": 7}, 456]' as body
)
select
id,
entry,
json_extract(entry, '$'),
json_extract(entry, '$.a'),
json_extract(entry, '$.b')
from
raw,
unnest(json_extract_array(body)) as entry
Я хочу предложить альтернативу. Поскольку массив является строкой, просто извлеките значение, используя regexp_extract_all:
REGEXP_EXTRACT_ALL(your_string, r'[0-9a-zA-Z][^"]+') as arr
Вы можете счесть, что регулярное выражение слишком ограничено, чтобы начинать с буквенно-цифровых символов; Вы можете просто настроить его по своему вкусу.
Было бы намного проще через JS
UDF.
CREATE TEMP FUNCTION
JSON_EXTRACT_ARRAY(input STRING)
RETURNS ARRAY<STRING>
LANGUAGE js AS """
return JSON.parse(input);
""";
WITH
k AS (
SELECT
'["a","b","c"]' AS x)
SELECT
JSON_EXTRACT_ARRAY(x) AS x
FROM
k