有没有可能把一个参数传递给CTE,让它选择一个节点,然后选择它的父节点,直到parentId为null的根?
在下面的代码中,如果我传入一个选择Rain Coats的参数,然后在树中向上递归到mens where,其中它的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发布于 2011-12-22 17:46:02
您当前的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更新
对于深度的逆序,您可以使用以下命令:
;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发布于 2011-12-22 17:49:04
目前,您的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 3https://stackoverflow.com/questions/8601965
复制相似问题