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

使用递归CTE将父ID与所有子ID合并为单行数组

递归CTE实现层级ID数组聚合

问题背景

现有pr表结构及数据如下:

stg source id, parent id
125, 124
126, 125
127, 125
128, 127 

需要生成视图,将顶层父节点(无上级节点的parent id)对应的所有层级子节点ID聚合为数组,预期结果:

parent id, stg_source_ids
124, [125, 126, 127, 128] 

原代码问题

原递归CTE仅实现了单层级ID追加,未向上聚合所有子节点数组,且未保留顶层父节点的统一标识,导致输出结果分散:

WITH RECURSIVE ParentChildHierarchy AS (
    SELECT pr.parent_id, pr.stg_source_id, 
    ARRAY_CONSTRUCT(pr.stg_source_id) AS stg_source_ids
    FROM pr
    WHERE NOT EXISTS (SELECT 1 FROM pr as pr2 WHERE 
    pr2.stg_source_id = pr.parent_id)

UNION ALL

SELECT pr.parent_id, pr.stg_source_id, 
array_append(p.stg_source_ids, pr.stg_source_id)
FROM pr JOIN ParentChildHierarchy p 
ON pr.parent_id = p.stg_source_id
)
SELECT * FROM ParentChildHierarchy;

执行结果:

124 -- [125]
125 -- [125, 126]
125 -- [125, 127]
127 -- [127, 128]

正确实现方案

方法1:基于顶层父节点标识的递归聚合

WITH RECURSIVE ParentChildHierarchy AS (
    -- 锚点成员:定位顶层父节点,初始化其直接子节点的数组
    SELECT 
        root.parent_id AS top_parent_id,
        pr.stg_source_id,
        ARRAY_CONSTRUCT(pr.stg_source_id) AS stg_source_ids
    FROM pr
    JOIN (
        -- 筛选所有顶层父节点(无对应stg source id的parent id)
        SELECT DISTINCT parent_id 
        FROM pr 
        WHERE NOT EXISTS (SELECT 1 FROM pr p2 WHERE p2.stg_source_id = pr.parent_id)
    ) root ON pr.parent_id = root.parent_id
    
    UNION ALL
    
    -- 递归成员:遍历子节点,将ID追加到对应顶层父节点的数组中
    SELECT 
        p.top_parent_id,
        child.stg_source_id,
        ARRAY_APPEND(p.stg_source_ids, child.stg_source_id)
    FROM ParentChildHierarchy p
    JOIN pr child ON p.stg_source_id = child.parent_id
),
-- 聚合同一顶层父节点的所有数组,合并为完整集合
AggregatedResults AS (
    SELECT 
        top_parent_id AS "parent id",
        ARRAY_UNION_AGG(stg_source_ids) AS stg_source_ids
    FROM ParentChildHierarchy
    GROUP BY top_parent_id
)
SELECT * FROM AggregatedResults;

方法2:从顶层向下递归收集

WITH RECURSIVE Hierarchy AS (
    -- 锚点:顶层父节点的直接子节点,记录顶层父ID并初始化数组
    SELECT 
        pr.parent_id AS top_parent,
        pr.stg_source_id,
        ARRAY_CONSTRUCT(pr.stg_source_id) AS stg_source_ids
    FROM pr
    WHERE NOT EXISTS (SELECT 1 FROM pr p2 WHERE p2.stg_source_id = pr.parent_id)
    
    UNION ALL
    
    -- 递归:遍历子节点,继承顶层父ID并追加当前节点ID到数组
    SELECT 
        h.top_parent,
        c.stg_source_id,
        ARRAY_APPEND(h.stg_source_ids, c.stg_source_id)
    FROM Hierarchy h
    JOIN pr c ON h.stg_source_id = c.parent_id
)
-- 聚合同一顶层父节点的所有数组
SELECT 
    top_parent AS "parent id",
    ARRAY_CAT_AGG(stg_source_ids) AS stg_source_ids
FROM Hierarchy
GROUP BY top_parent;

说明

  • 两种方法核心都是保留顶层父节点的统一标识,确保所有层级子节点都关联到同一个顶层父节点。
  • 利用ARRAY_UNION_AGG或ARRAY_CAT_AGG聚合所有分散的数组,得到完整的子节点ID集合。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 09:40:40