我有一个带有递归层次结构的表(即ID,ParentID)。对于此层次结构中的任何项目,我希望能够返回层次结构的上下两个列表以及每行的级别。假设父母只能拥有一个孩子。
举例如下:
ID ParentID
--------------
1 NULL
2 1
3 2
4 NULL
5 4
6 5
鉴于ID 1,2或3,我想返回:
ID ParentID Level
-----------------------
1 NULL 1
2 1 2
3 2 3
我以前做过这个,但我不记得怎么做了。我知道解决方案涉及CTE,我无法做到正确!任何帮助表示赞赏。
答案 0 :(得分:5)
;with cte as
(
select *, 1 as level from @t where id = @yourid
union all
select t.*, level - 1
from cte
inner join @t t on cte.parent = t.id
),
cte2 as
(
select * from cte
union all
select t.*, level+1
from cte2
inner join @t t on cte2.id = t.parent
)
select id,parent, ROW_NUMBER() over (order by level) level
from ( select distinct id, parent, level from cte2) v
答案 1 :(得分:0)
我能提出的最准确的CTE查询版本是:
WITH Ancestry (AncestorID, DescendantID)
AS
(
SELECT
ParentID, ID
FROM
dbo.Location
WHERE
ParentID IS NOT NULL
UNION ALL
SELECT
P.AncestorID, C.ID
FROM
dbo.Location C
JOIN
Ancestry P on C.ParentID = P.DescendantID
)
SELECT * FROM Ancestry
结果是表格中存在的所有祖先/后代关系的列表。
最终的“SELECT * FROM Ancestry”可以用更复杂的东西代替,以便过滤,订购等。
要包含自反关系,可以通过在最终的SELECT语句中添加两行来修改查询:
SELECT * FROM Ancestry
UNION
SELECT ID, ID FROM dbo.Location
答案 2 :(得分:-1)
;WITH Recursive_CTE AS (
SELECT
child.ExecutiveId,
CAST(child.ExecutiveName as varchar(100)) BusinessUnit,
CAST(NULL as bigint) ParentUnitID,
CAST(NULL as varchar(100)) ParentUnit,
CAST('' as varchar(100)) LVL,
CAST(child.ExecutiveId as varchar(100)) Hierarchy,
1 AS RecursionLevel
FROM Sales_Executive_level child
WHERE ExecutiveId = 4000 --your Id which you want to get all parent node
UNION ALL
SELECT
child.ExecutiveId,
CAST(LVL + child.ExecutiveName as varchar(100)) AS BusinessUnit,
child.ParentExecutiveID,
parent.BusinessUnit ParentUnit,
CAST('' + LVL as varchar(100)) AS LVL,
CAST(Hierarchy + ':' + CAST(child.ExecutiveId as varchar(100)) as varchar(100)) Hierarchy,
RecursionLevel + 1 AS RecursionLevel
FROM Recursive_CTE parent
INNER JOIN Sales_Executive_level child ON child.ParentExecutiveID = parent.ExecutiveId
)
SELECT * FROM Recursive_CTE ORDER BY Hierarchy
OPTION (MAXRECURSION 300);