SQL Server CTE选择直到根的单个树分支结构

是否有可能将一个参数传递给一个CTE来选择一个节点,然后选择它的父母直到parentId为空的根?

在下面的代码中,如果我传入一个选择Rain Coats的参数,然后将树重新递归到其parentId为null的位置,并选择该分支中的所有节点(包括子节点)。 请有人可以帮我解决这个问题。 我的例子只是递归并显示深度

SQL示例:

DECLARE @Department TABLE
(
    Id INT NOT NULL,
    Name varchar(50) NOT NULL,
    ParentId int NULL
)

INSERT INTO @Department SELECT 1, 'Toys', null
INSERT INTO @Department SELECT 2, 'Computers', null
INSERT INTO @Department SELECT 3, 'Consoles', 2
INSERT INTO @Department SELECT 4, 'PlayStation 3', 3
INSERT INTO @Department SELECT 5, 'Xbox 360', 2
INSERT INTO @Department SELECT 6, 'Games', 1
INSERT INTO @Department SELECT 7, 'Puzzles', 6
INSERT INTO @Department SELECT 8, 'Mens Wear', null
INSERT INTO @Department SELECT 9, 'Mens Clothing', 8
INSERT INTO @Department SELECT 10, 'Jackets', 9
INSERT INTO @Department SELECT 11, 'Rain Coats', 10

;WITH c 
AS
(
    SELECT Id, Name,1 AS Depth
    FROM @Department
    WHERE ParentId is null  

         UNION ALL

         SELECT t.Id, t.Name, c.Depth + 1 AS 'Level'
    FROM @Department T  
    JOIN c ON t.ParentId = c.Id

)
SELECT * FROM c WHERE c.Id = 3

您当前的CTE仅显示树中的所有项目,其Depth和所有其他属性。 因此,它工作正常。

要做你正在寻找的东西,你必须几乎“反转”CTE - 先抓住你感兴趣的物品,作为CTE的“锚点”,然后“递增”到根部:

DECLARE @StartID INT = 11

;WITH c 
AS
(
    SELECT Id, ParentId, Name, 1 AS Depth
    FROM @Department
    WHERE Id = @startID

    UNION ALL

    SELECT t.Id, t.ParentId, t.Name, c.Depth + 1 AS 'Level'
    FROM @Department T  
    INNER JOIN c ON t.Id = c.ParentId
)
SELECT * 
FROM c 

这将做你正在寻找和输出的内容:

Id ParentId  Name            Depth
11    10     Rain Coats        1
10     9     Jackets           2
 9     8     Mens Clothing     3
 8   NULL    Mens Wear         4

更新

对于Depth的逆序,您可以使用这个:

;WITH c 
AS
(
    SELECT Id, ParentId, Name, 1 AS Depth
    FROM @Department
    WHERE Id = @startID

    UNION ALL

    SELECT t.Id, t.ParentId, t.Name, c.Depth + 1 AS 'Level'
    FROM @Department T  
    INNER JOIN c ON t.Id = c.ParentId
)
SELECT Id,
       ParentID, 
       Name,
       MAX(Depth) OVER() - Depth + 1 AS InverseDepth
FROM c

从这里输出:

Id ParentId  Name            InverseDepth
11    10     Rain Coats        4
10     9     Jackets           3
 9     8     Mens Clothing     2
 8   NULL    Mens Wear         1

目前,您的CTE具有根作为它的锚,并且在其递归部分中从父母到孩子。 如果你想要整棵树,你需要从感兴趣的孩子开始,然后继续前进。 这是做到这一点的一种方法。 我已经引入了一个新的列StartingId ,它在我们走上树时保持不变 - 这是我们将基于以下内容选择的:

;WITH c 
AS
(
    SELECT Id AS StartingId, Id, ParentId, Name, 0 AS Height
    FROM @Department

    UNION ALL

    SELECT c.StartingId, p.Id, p.ParentId, p.Name, c.Height + 1 AS Height
    FROM @Department p INNER JOIN c ON p.Id = c.ParentId
)
SELECT * FROM c WHERE c.StartingId = 11

StartingId  Id          ParentId    Name                                   Height
----------- ----------- ----------- ----------------------------------------------
11          11          10          Rain Coats                             0
11          10          9           Jackets                                1
11          9           8           Mens Clothing                          2
11          8           NULL        Mens Wear                              3
链接地址: http://www.djcxy.com/p/60221.html

上一篇: SQL Server CTE select single tree branch structure upto the root

下一篇: CTE Hierachy descending but picking up child nodes not parents from ancestor