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
      }); 
  }"
)  
Другие вопросы по тегам