ARRAY_AGG(STRUCT(x,y,z)) equivalent in Bigquery legacy SQL



我有一个以下结构的标准SQL查询

SELECT a, ARRAY_AGG(STRUCT(x,y,z))
FROM t
GROUP BY a

如何在旧版 SQL 中编写相同的查询?

无法使用旧版 SQL 对非叶字段进行 NEST 处理。唯一的解决方法是将 x,y,z 打包到一个字符串中(例如构造 JSON(,然后在其上使用 NEST,并且每当需要单个字段时,使用一些字符串解析函数或 Javascript UDF。不用说,使用标准SQL要简单得多。

同时,如果您仍然需要在 BigQuery Legacy SQL 中使用它 - 请参阅下面的简单示例。

大查询标准 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 旧版 SQL 版本(确保设置目标表并将平展结果设置为关闭 - 否则 UI 将平展输出(

#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
      }); 
  }"
)  

最新更新