如何使用sql查询从表中获取嵌套子ID

时间:2018-05-25 08:48:11

标签: sql sql-server common-table-expression

我有两个表,Table1和Table2。 Table1具有需要从树中排除的SectionID。 enter image description here

Table2拥有ParentID及其ChildID。有一个场景A parentID有一个孩子,它是另一个孩子的父母,依此类推。我需要从Table2获取表1中所有parentID的childID。

示例表1具有SectionId 20000448,其是20000449的父级,其是20000543的父级(参见下图)。我需要获得2000448的所有childIds和subchildIds。

即,结果应该是2000448(表1中的表示)有childIds 20000449,20000450,20000452,20000543,20000544,20000490,20000739,20000740,20000741。 (这里我从20000449开始使用SubchildID。如果20000450有子ID,则还需要考虑它们。)

我曾尝试过使用CTE,但没有给出预期的结果。

enter image description here

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

假设您使用的是SQL Server,这似乎是一个非常简单的递归。没有文本示例很难测试,但尝试使用以下内容:

;WITH Hierarchy AS 
(
    SELECT DISTINCT
        RootID = T.ParentID,
        DescendantID = T.ParentID,
        Level = 0
    FROM
        Table2 AS T
    WHERE
        NOT EXISTS (SELECT 'records without parents' FROM Table2 AS N WHERE N.ChildID = T.ParentID)

    UNION ALL

    SELECT
        RootID = H.RootID,
        DescendantID = T.ChildID,
        Level = H.Level + 1
    FROM
        Hierarchy AS H
        INNER JOIN Table2 AS T ON H.DescendantID = T.ParentID
)
SELECT
    H.RootID,
    H.DescendantID,
    H.Level
FROM
    Hierarchy AS H
ORDER BY
    H.RootID,
    H.Level

要从Table1中排除记录,您可以在结束时或在递归时使用NOT EXISTS,具体取决于您的需要(在递归时停止将使来自{{1}的记录的后子项无效})。

编辑:使用示例数据和临时表:

Table1

结果:

IF OBJECT_ID('tempdb..#Table2') IS NOT NULL
    DROP TABLE #Table2

CREATE TABLE #Table2 (
    ChildID INT,
    ParentID INT)

INSERT INTO #Table2 (
    ChildID,
    ParentID)
VALUES
    (20000449, 20000448),
    (20000450, 20000448),
    (20000452, 20000448),

    (20000543, 20000449),
    (20000544, 20000449),

    (20000490, 20000543),

    (20000739, 20000490),
    (20000740, 20000490),
    (20000741, 20000490)

;WITH Hierarchy AS 
(
    SELECT DISTINCT
        RootID = T.ParentID,
        DescendantID = T.ParentID,
        Level = 0
    FROM
       #Table2 AS T
    WHERE
        NOT EXISTS (SELECT 'records without parents' FROM #Table2 AS N WHERE N.ChildID = T.ParentID)

    UNION ALL

    SELECT
        RootID = H.RootID,
        DescendantID = T.ChildID,
        Level = H.Level + 1
    FROM
        Hierarchy AS H
        INNER JOIN #Table2 AS T ON H.DescendantID = T.ParentID
)
SELECT
    H.RootID,
    H.DescendantID,
    H.Level
FROM
    Hierarchy AS H
ORDER BY
    H.RootID,
    H.Level