ARRAY_AGG(STRUCT(x,y,z)) эквивалент в устаревшем SQL Bigquery
У меня есть стандартный запрос SQL следующей структуры
SELECT a, ARRAY_AGG(STRUCT(x,y,z))
FROM t
GROUP BY a
Как можно написать тот же запрос в устаревшем SQL?
2 ответа
Решение
Невозможно NEST не листовых полей с использованием устаревшего SQL. Единственный обходной путь - это упаковать x,y,z в строку (например, создать JSON), а затем использовать NEST
и всякий раз, когда требуются отдельные поля, используйте некоторую функцию синтаксического анализа строки или Javascript UDF. Само собой разумеется, это намного проще со стандартным SQL.
Между тем, если вам все еще нужно иметь его в BigQuery Legacy SQL - см. Простой пример ниже.
BigQuery Стандартная версия SQL
#standardSQL
WITH t AS (
SELECT 1 AS a, 11 AS x, 12 AS y, 13 AS z UNION ALL
SELECT 2 AS a, 21 AS x, 22 AS y, 23 AS z UNION ALL
SELECT 3 AS a, 31 AS x, 32 AS y, 33 AS z
)
SELECT
a, ARRAY_AGG(STRUCT(x, y, z)) AS aa
FROM t
GROUP BY a
Версия BigQuery Legacy SQL (убедитесь, что вы установили таблицу назначения и отключили вывод результатов - иначе пользовательский интерфейс сгладит вывод)
#legacySQL
SELECT a, aa.*
FROM JS(
( // input table
SELECT
a, GROUP_CONCAT(CONCAT(STRING(x), ';', STRING(y), ';', STRING(z))) AS aa
FROM
(SELECT 1 AS a, 11 AS x, 12 AS y, 13 AS z),
(SELECT 2 AS a, 21 AS x, 22 AS y, 23 AS z),
(SELECT 3 AS a, 31 AS x, 32 AS y, 33 AS z)
GROUP BY a
),
a, aa, // input columns
"[ // output schema
{name: 'a', type:'integer'},
{name: 'aa', type:'record', mode:'repeated',
fields: [
{name: 'x', type: 'integer'},
{name: 'y', type: 'integer'},
{name: 'z', type: 'integer'}
]}
]",
"function(row, emit) { // function
var aa = [];
aa1 = row.aa.split(',');
for (var i = 0; i < aa1.length; i++) {
aa2 = aa1[i].split(';');
aa.push({x:parseInt(aa2[0]), y:parseInt(aa2[1]), z:parseInt(aa2[2])});
};
emit({
a: row.a,
aa: aa
});
}"
)