SQL Find Top Parent - PullRequest
       25

SQL Find Top Parent

0 голосов
/ 25 января 2019

У меня есть эта таблица:

Id  ParentId    LevelName
1   0           XXXX
2   0           XXXX
4   2           XXXX
5   2           XXXX
6   2           XXXX
7   2           XXXX
8   2           XXXX
9   2           XXXX
18  2           XXXX
19  18          XXXX
20  19          XXXX

Я хочу ParentId верхнего уровня из этого, как.Если я передам Id 20, он вернет 2, то есть Id верхнего уровня в таблице:

 Id ParentId    LevelName
 2  0           XXXX

Моя попытка:

WITH cteReports (LvlID, PrntID, LevelID) AS
    (SELECT Id,
            ParentId,
            1
     FROM Levels
     WHERE Id = @ParentId
     UNION ALL
     SELECT e.Id,
            e.ParentId,
            r.LevelID + 1
     FROM Levels e
          INNER JOIN cteReports r ON e.ParentId = r.LvlID)
SELECT Id
FROM Levels
WHERE Id IN (SELECT LvlID FROM cteReports);

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Самая большая проблема заключалась в том, что ваше объединение перевернуло таблицы.

DECLARE @Levels TABLE(
    ID INT,
    ParentID INT,
    LevelName VARCHAR(20)
)   
INSERT INTO @Levels (ID,ParentID,LevelName) SELECT 1   ,0           ,'XXXX'
INSERT INTO @Levels (ID,ParentID,LevelName) SELECT 2   ,0           ,'XXXX'
INSERT INTO @Levels (ID,ParentID,LevelName) SELECT 4   ,2           ,'XXXX'
INSERT INTO @Levels (ID,ParentID,LevelName) SELECT 5   ,2           ,'XXXX'
INSERT INTO @Levels (ID,ParentID,LevelName) SELECT 6   ,2           ,'XXXX'
INSERT INTO @Levels (ID,ParentID,LevelName) SELECT 7   ,2           ,'XXXX'
INSERT INTO @Levels (ID,ParentID,LevelName) SELECT 8   ,2           ,'XXXX'
INSERT INTO @Levels (ID,ParentID,LevelName) SELECT 9   ,2           ,'XXXX'
INSERT INTO @Levels (ID,ParentID,LevelName) SELECT 18  ,2           ,'XXXX'
INSERT INTO @Levels (ID,ParentID,LevelName) SELECT 19  ,18          ,'XXXX'
INSERT INTO @Levels (ID,ParentID,LevelName) SELECT 20  ,19          ,'XXXX'

DECLARE @TargetID INT=20;

WITH cteReports (Id, ParentId, LevelID) AS
(
    SELECT Id,
        ParentId,
        1
    FROM @Levels
    WHERE Id = @TargetID
    UNION ALL
    SELECT e.Id,
        e.ParentId,
        r.LevelID + 1
    FROM @Levels e
    INNER JOIN cteReports r ON r.ParentId = e.Id
)
SELECT lvl.*
FROM @Levels lvl
INNER JOIN cteReports cte ON cte.ID=lvl.ID
WHERE LevelID = (
    SELECT MAX(LevelID) AS MaxLevelID
    FROM cteReports
)
0 голосов
/ 25 января 2019

Это должно сделать это:

DECLARE @start_id INT = 20;
WITH rcte AS (
    SELECT *
    FROM t
    WHERE id = @start_id

    UNION ALL

    SELECT curr.*
    FROM t    AS curr
    JOIN rcte AS prev ON curr.id = prev.parentid
)
SELECT *
FROM rcte
WHERE parentid = 0
...