2

我有一個遞歸層次結構(即ID,ParentID)的表。對於此層次中的任何項目,我希望能夠將層次結構中的所有內容以及每行的層次帶回列表。假設父母只能生一個孩子。CTE返回層次結構中的所有項目

舉個例子如下:

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

可能重複[如何找到在SQL Server表的表列的所有孩子?(http://stackoverflow.com/questions/12625775/how-to-find-all-child-of- a-table-column-in-sql-server-table) – cadrell0

+0

@ cadrell0。我需要父母和孩子爲任何給定的ID。 –

回答

4
;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 
+0

優秀,它的作品完美。只是爲了厚臉皮...你能想出一種方法來優化這個,通過在最後刪除嵌套選擇的需要嗎? –

+0

取決於你是否想要它們? – podiluska

+0

我正在使用此查詢的結果來返回更多信息,因此我將最終以日期順序返回數據(包含關聯的數據)。所以簡單來說,不,我只需要ID和Level。 –

-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); 
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譜」可以用更復雜的東西過濾,順序等

及時更換,包括反身關係,查詢可以通過增加兩行到最後的SELECT語句修改:

SELECT * FROM Ancestry 
UNION 
SELECT ID, ID FROM dbo.Location 
+0

我把這個查詢放到一個視圖中,但不知道這是否是最佳做法。 – Hutch