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

T-SQL递归查询:获取含祖先节点关联表T2的全量数据

这个需求我之前处理过类似的,用T-SQL的递归CTE就能完美解决,给你一步步拆解清楚:

解决方案:递归CTE + 关联查询

核心思路是先获取每个ClassID的所有祖先节点(包括自身),再关联T2表拿到对应的所有数据。

1. 先准备测试数据(方便你对照验证)

先模拟示例中的T1层级表和T2关联表,你可以直接运行这段代码创建测试环境:

-- 创建T1层级表
CREATE TABLE T1 (
    ClassID INT PRIMARY KEY,
    ParentClassID INT NULL FOREIGN KEY REFERENCES T1(ClassID)
);

INSERT INTO T1 (ClassID, ParentClassID)
VALUES 
(1, NULL),  -- 根节点
(2, 1),
(3, 2),
(4, 1),
(5, 4);

-- 创建T2关联数据表
CREATE TABLE T2 (
    ID INT IDENTITY(1,1) PRIMARY KEY,
    ClassID INT NOT NULL FOREIGN KEY REFERENCES T1(ClassID),
    DataValue VARCHAR(50) NOT NULL
);

INSERT INTO T2 (ClassID, DataValue)
VALUES
(1, 'A'),
(1, 'B'),
(2, 'C'),
(3, 'D'),
(4, 'E'),
(5, 'F');

2. 用递归CTE获取所有祖先节点(含自身)

递归CTE分两部分:

  • 锚点成员:先把每个ClassID自身加入结果集
  • 递归成员:不断向上查找父节点,直到找到根节点(ParentClassID为NULL)
WITH ClassHierarchy AS (
    -- 锚点:每个节点自身
    SELECT 
        ClassID AS OriginalClassID,  -- 记录原始的ClassID
        ClassID AS HierarchyClassID, -- 当前遍历到的层级节点ID
        ParentClassID
    FROM T1

    UNION ALL

    -- 递归:向上查找父节点
    SELECT 
        ch.OriginalClassID,
        t.ClassID AS HierarchyClassID,
        t.ParentClassID
    FROM ClassHierarchy ch
    JOIN T1 t ON ch.ParentClassID = t.ClassID
)

3. 关联T2表获取最终结果

把上面的CTE和T2表关联,就能得到每个原始ClassID对应的所有自身+祖先的T2数据:

WITH ClassHierarchy AS (
    SELECT 
        ClassID AS OriginalClassID,
        ClassID AS HierarchyClassID,
        ParentClassID
    FROM T1

    UNION ALL

    SELECT 
        ch.OriginalClassID,
        t.ClassID AS HierarchyClassID,
        t.ParentClassID
    FROM ClassHierarchy ch
    JOIN T1 t ON ch.ParentClassID = t.ClassID
)
SELECT 
    ch.OriginalClassID,       -- 原始的ClassID
    t2.ClassID AS SourceClassID, -- 提供数据的节点ID(自身或祖先)
    t2.DataValue              -- 对应的T2数据
FROM ClassHierarchy ch
JOIN T2 t2 ON ch.HierarchyClassID = t2.ClassID
ORDER BY ch.OriginalClassID, t2.ClassID;

结果示例

比如对于OriginalClassID=3,它的祖先节点是2、1,所以结果会包含:

  • 3自身的T2数据:D
  • 父节点2的T2数据:C
  • 祖父节点1的T2数据:A、B

特殊情况处理

如果你的T1表存在循环引用(比如ClassID=2的ParentClassID指向3,形成闭环),可以在递归CTE里加入路径校验避免死循环:

WITH ClassHierarchy AS (
    SELECT 
        ClassID AS OriginalClassID,
        ClassID AS HierarchyClassID,
        ParentClassID,
        -- 用字符串记录遍历路径,防止循环
        CAST(',' + CAST(ClassID AS VARCHAR(10)) + ',' AS VARCHAR(MAX)) AS NodePath
    FROM T1

    UNION ALL

    SELECT 
        ch.OriginalClassID,
        t.ClassID AS HierarchyClassID,
        t.ParentClassID,
        ch.NodePath + CAST(t.ClassID AS VARCHAR(10)) + ','
    FROM ClassHierarchy ch
    JOIN T1 t ON ch.ParentClassID = t.ClassID
    -- 排除已经在路径里的节点,避免循环
    WHERE ch.NodePath NOT LIKE '%,' + CAST(t.ClassID AS VARCHAR(10)) + ',%'
)
-- 后续关联T2的逻辑不变
SELECT 
    ch.OriginalClassID,
    t2.ClassID AS SourceClassID,
    t2.DataValue
FROM ClassHierarchy ch
JOIN T2 t2 ON ch.HierarchyClassID = t2.ClassID
ORDER BY ch.OriginalClassID, t2.ClassID;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:06:02