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

在GBQ(SQL)中拼接不同长度的结构体/数组

解决方案:按数组索引关联后重新聚合

要实现将两个长度不同的数组按位置配对(短数组补NULL),核心思路是先将数组拆分为带索引的行,再按索引关联,最后重新聚合为目标数组。以下是具体实现步骤:

步骤1:为两个表的数组元素添加索引

先分别对两个聚合后的表进行UNNEST操作,同时用OFFSET()获取每个元素在数组中的位置索引:

处理数值表(第一个表)

WITH value_table AS (
  -- 原第一个表的聚合逻辑
  WITH source_data AS (
    SELECT 'MMTT' AS client_id, CAST('2022-10-13' AS DATE) AS session_date, 1 AS value UNION ALL
    SELECT 'MMTT', CAST('2022-10-13' AS DATE), 2 UNION ALL
    SELECT 'MMTT', CAST('2022-10-13' AS DATE), 3 UNION ALL
    SELECT 'MMTT', CAST('2022-10-14' AS DATE), 1 UNION ALL
    SELECT 'MMTT', CAST('2022-10-14' AS DATE), 2 UNION ALL
    SELECT 'MMTT', CAST('2022-10-14' AS DATE), 3
  )
  SELECT 
    client_id, 
    session_date, 
    ARRAY_AGG(STRUCT(value)) AS value_info
  FROM source_data
  GROUP BY 1,2
),
-- 拆分数组并添加索引
value_with_index AS (
  SELECT
    client_id,
    session_date,
    elem.value,
    idx AS pos  -- 获取元素在数组中的位置
  FROM value_table, UNNEST(value_info) AS elem WITH OFFSET idx
)

处理语言表(第二个表)

, language_table AS (
  -- 原第二个表的聚合逻辑
  WITH source_data AS (
    SELECT 'MMTT' AS client_id, CAST('2022-10-13' AS DATE) AS session_date, 'French' AS languages UNION ALL
    SELECT 'MMTT', CAST('2022-10-13' AS DATE), 'English' UNION ALL
    SELECT 'MMTT', CAST('2022-10-14' AS DATE), 'French' UNION ALL
    SELECT 'MMTT', CAST('2022-10-14' AS DATE), 'English'
  )
  SELECT 
    client_id, 
    session_date, 
    ARRAY_AGG(STRUCT(languages)) AS languages_info
  FROM source_data
  GROUP BY 1,2
),
-- 拆分数组并添加索引
language_with_index AS (
  SELECT
    client_id,
    session_date,
    elem.languages,
    idx AS pos
  FROM language_table, UNNEST(languages_info) AS elem WITH OFFSET idx
)

步骤2:按索引关联并重新聚合

使用FULL JOIN确保两个表的所有索引都被保留(短数组的缺失索引会补NULL),然后按client_id、session_date分组,重新聚合为目标数组:

SELECT
  COALESCE(v.client_id, l.client_id) AS client_id,
  COALESCE(v.session_date, l.session_date) AS session_date,
  ARRAY_AGG(STRUCT(v.value, l.languages) ORDER BY COALESCE(v.pos, l.pos)) AS combined_info
FROM value_with_index v
FULL JOIN language_with_index l
  ON v.client_id = l.client_id
  AND v.session_date = l.session_date
  AND v.pos = l.pos
GROUP BY 1,2

说明

  • UNNEST ... WITH OFFSET:将数组拆分为每行一个元素,同时获取元素在原数组中的位置索引,这是实现按位置配对的核心。
  • FULL JOIN:保证两个表中所有位置的元素都被关联,短数组中没有对应位置的元素会填充NULL。
  • ARRAY_AGG ... ORDER BY pos:重新聚合时按索引排序,确保元素顺序与原数组一致。

执行上述SQL后,即可得到预期的输出结构:每个元素包含对应位置的value和languages,短数组的缺失位置补NULL。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:43:21