Как получить вложенные дочерние идентификаторы из таблицы с помощью SQL-запроса - PullRequest
0 голосов
/ 25 мая 2018

У меня есть две таблицы, Таблица1 и Таблица2.Таблица1 имеет разделы, которые должны быть исключены из дерева.enter image description here

В Table2 есть ParentID и его ChildID.Существует сценарий. У parentID есть дочерний элемент, который является родителем другого дочернего элемента и т. Д.Мне нужно получить все childID идентификатора parentID, присутствующего в Таблице 1, из Таблицы 2.

Пример Таблица1 имеет SectionId 20000448, который является родителем 20000449, который является родителем 20000543 (см. Изображение ниже).Мне нужно получить все childIds и subchildIds 2000448.

, т. Е. Результат должен быть 2000448 (который представлен в Таблице 1) с childIds 20000449,20000450,20000452,20000543,20000544,20000490,20000739,20000740,20000741,(Здесь я беру SubchildID из 20000449. Если 20000450 имеет childID, их также необходимо учитывать.)

Я пытался использовать CTE, но он не дает ожидаемого результата.

enter image description here

Любая помощь будет оценена.

1 Ответ

0 голосов
/ 25 мая 2018

Предполагается, что вы используете 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 в конце или в рекурсии, в зависимости от ваших потребностей(остановка при рекурсии сделает недействительными задних потомков записей из 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

Результат:

RootID  DescendantID    Level
20000448    20000448    0
20000448    20000449    1
20000448    20000450    1
20000448    20000452    1
20000448    20000543    2
20000448    20000544    2
20000448    20000490    3
20000448    20000739    4
20000448    20000740    4
20000448    20000741    4
...