【问题标题】:Retrieving all descendants of an Id in SQL Server在 SQL Server 中检索 Id 的所有后代
【发布时间】:2013-06-05 09:30:41
【问题描述】:

我有一个包含workgroup_idparent_id 的父子(多对多)表(一个工作组可能有多个父子)。

我需要将每个父母的所有后代(即孙子、曾孙等)插入到目标表中,级别数未知并且可以更改。 例如我原来的表是:

wpwpr_workgroup wpwpr_parent
4   3
5   3
6   3
7   3
8   3
9   3
10  3
11  10
12  10
13  10
14  3
15  3
16  3
17  16
18  16
19  16
20  3
21  20
22  20
23  20
24  16
25  16
26  16
27  28
28  3
30  3
31  3
32  3
33  3
34  3

我的目标表需要如下所示:

wpwpr_workgroup wpwpr_parent
10  3
11  3
12  3
16  3
17  3
18  3
11  10
12  10
17  16
18  16

任何想法如何实现这一目标?我想这需要某种递归,但我不太确定如何去做

非常感谢 问候 兹维

【问题讨论】:

    标签: sql-server recursion many-to-many parent-child


    【解决方案1】:

    递归 CTE 可能是答案 - 但是,如果您的结构可以有多个父母/循环祖先,那就很混乱了。

    您还可以通过基于集合的循环获得相当有效的解决方案(循环的每次迭代都会对最后写入的集合进行父搜索,并检查节点是否已存在于答案集中。

    如果您发布更多示例数据,我们可能会给您一些 SQL 来帮助您入门。

    另外——您使用的是什么版本的 SQL Server? CTE 仅在 2005 年以上提供

    对于您发布的数据,这将起作用:

        USE tempdb
    GO
    
    IF OBJECT_ID('tempdb..#sample') IS NOT NULL DROP TABLE #sample
    GO
    
    CREATE TABLE #sample (
          wpwpr_workgroup INT
        , wpwpr_parent INT
        )
    INSERT #sample (wpwpr_workgroup, wpwpr_parent)
    VALUES
          (10,  3)
        , (11,  10)
        , (12,  10)
        , (16,  3)
        , (17,  16)
        , (18,  16)
    GO
    
    SELECT * FROM #sample
    
    -- CTE
    ; WITH descendants AS (
        -- Anchor Definition
        SELECT wpwpr_workgroup AS [workGroup]
             , wpwpr_parent AS [Parent]
        FROM #sample
        -- Recursive Definition
        UNION ALL SELECT
            d.[workGroup] AS [workGroup]
             , s.wpwpr_parent AS [Parent]
        FROM
            descendants AS d
            JOIN #sample AS s ON s.wpwpr_workgroup = d.[Parent]
        )
    SELECT * FROM descendants ORDER BY [workGroup], [Parent]
    

    结果是:

    workGroup   Parent
    ----------- -----------
    10          3
    11          3
    11          10
    12          3
    12          10
    16          3
    17          3
    17          16
    18          3
    18          16
    
    (10 row(s) affected)
    

    【讨论】:

    • 嗨 Charlie 感谢您的快速响应,我使用的是 SQL Server 2008R2,我是该领域的新手,您可以给我看一个简短的代码示例吗?
    • 完成——如果你有循环祖先,递归 CTE 可能会变得混乱。所以你的里程可能会有所不同。
    • 对于 SQL Server 新手来说,这是一个相当高级的话题。阅读此处了解 CTE 的低点:msdn.microsoft.com/en-us/library/ms190766%28v=sql.105%29.aspx
    • Thnks Charlie,似乎可以像我需要的那样工作,尽管我必须对我的桌子进行更深入的检查。我知道如何使用 CTE,只是递归的概念对我来说有点难以掌握。再次非常感谢。兹维
    猜你喜欢
    • 2018-07-22
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    相关资源
    最近更新 更多