You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BigQuery左连接查询中如何对嵌套表所有字段执行Group By操作

方案1:预聚合子表(最优方案,无需分组)

你原来的逐轮连接后分组的写法可以直接优化为提前聚合所有子表,完全规避主表/中间表的分组需求,同时性能更优,且天然保留Table1中ID相同但其他字段不同的独立行:

WITH
-- 预聚合所有需要嵌套的子表,提前按ID生成嵌套数组
agg_table2 AS (
  SELECT ID, ARRAY_AGG((SELECT AS STRUCT t.* EXCEPT(ID))) AS Table2
  FROM Table2 t
  GROUP BY ID
),
agg_table3 AS (
  SELECT ID, ARRAY_AGG((SELECT AS STRUCT t.* EXCEPT(ID))) AS Table3
  FROM Table3 t
  GROUP BY ID
),
-- 以此类推生成agg_table4到agg_table10
agg_table10 AS (
  SELECT ID, ARRAY_AGG((SELECT AS STRUCT t.* EXCEPT(ID))) AS Table10
  FROM Table10 t
  GROUP BY ID
)

-- 直接与主表左连接即可,主表所有行都会完整保留
SELECT 
  t1.*,
  IFNULL(t2.Table2, []) AS Table2,
  IFNULL(t3.Table3, []) AS Table3,
  -- 依次补全到Table10
  IFNULL(t10.Table10, []) AS Table10
FROM Table1 t1
LEFT JOIN agg_table2 t2 USING(ID)
LEFT JOIN agg_table3 t3 USING(ID)
-- 依次连接到agg_table10
LEFT JOIN agg_table10 t10 USING(ID)

方案2:沿用逐轮嵌套写法的修复方案

如果你的业务逻辑必须保留逐轮生成R表的结构,可以通过序列化整行作为分组键,等效实现按所有字段分组的效果:

R1 AS(
  SELECT ANY_VALUE(t1).*, ARRAY_AGG(( SELECT AS STRUCT Table2.* EXCEPT(ID))) AS Table2
  FROM Table1 t1 LEFT JOIN Table2 USING(ID)
  -- 序列化整行作为分组键,等效按Table1所有字段分组
  GROUP BY TO_JSON_STRING(t1)
),
R2 AS(
  SELECT ANY_VALUE(r1).*, ARRAY_AGG(( SELECT AS STRUCT Table3.* EXCEPT(ID))) AS Table3
  FROM R1 r1 LEFT JOIN Table3 USING(ID)
  -- 中间R表也直接序列化整行分组
  GROUP BY TO_JSON_STRING(r1)
),
-- 以此类推到R9
SELECT ANY_VALUE(r9).*, ARRAY_AGG(( SELECT AS STRUCT Table10.* EXCEPT(ID))) AS Table10
FROM R9 r9 LEFT JOIN Table10 USING(ID)
GROUP BY TO_JSON_STRING(r9)

原理说明

TO_JSON_STRING函数会将整行的所有字段值序列化为唯一字符串,内容完全相同的行会生成相同的字符串,以此作为分组键即可实现按整行所有字段分组的需求,兼容包含嵌套字段的场景。


内容的提问来源于stack exchange,提问作者Harvey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 11:24:10