2012-11-21 47 views
3

我擁有下表的Class Hierarchy結構。使用SQL Server CTE返回所有父記錄

ClassID ParentID 
-------------------- 
PMM_00001 null 
PMM_00010 PMM_00001 
PMM_00110 PMM_00010 
PMM_00020 PMM_00001 
PMM_00220 PMM_00020 

我想獲得以下結果。

ClassID Class_Join 
--------------------- 
PMM_00001 PMM_00001 
PMM_00010 PMM_00001 
PMM_00010 PMM_00010 
PMM_00110 PMM_00001 
PMM_00110 PMM_00010 
PMM_00110 PMM_00110 
PMM_00020 PMM_00001 
PMM_00020 PMM_00020 
PMM_00220 PMM_00001 
PMM_00220 PMM_00020 
PMM_00220 PMM_00220 

我打算使用這些結果通過加入我的特徵表來獲得繼承特徵。在過去,我已經使用循環來正確地獲取數據,但是我想使用CTE來獲得這些結果。

這是我到目前爲止嘗試過的。

;WITH ClassHierarchy_CTE (ClassID, ClassID_Join) 
AS 
(
SELECT 
    c.ClassID, 
    c.ClassID 
FROM 
    ClassHierarchy AS h 
WHERE 
    h.ParentID IS NULL 
UNION ALL 
SELECT 
    c.ClassID, 
    h.ParentID 
FROM 
    ClassHierarchy AS h INNER JOIN ClassHierarchy_CTE 
     ON 
      h.ParentID = ClassHierarchy_CTE.ClassID 
) 
SELECT 
    * 
FROM 
    ClassHierarchy_CTE 
ORDER BY 
    ClassID 

我從這裏得到的結果只是走下層次結構以獲得完整列表。我需要將參考返回到層次結構中的每個級別,以便我可以獲得完整的特徵列表。任何幫助表示讚賞!如果有更好的方法來做到這一點,我願意接受建議。

回答

5

看起來我接近這一切都是錯誤的。我缺少的概念是我需要移動UP的層次結構,而不是DOWN(因爲大多數文檔/文章在那裏演示)。所以這就是我所做的。

CREATE TABLE hierarchy 
(
    ClassID nvarchar(100), ParentID nvarchar(100) 
) 

INSERT INTO hierarchy 
(ClassID  ,   ParentID) 
VALUES 
(N'PMM_00001',  NULL ), 
(N'PMM_00010',  N'PMM_00001'), 
(N'PMM_00110',  N'PMM_00010'), 
(N'PMM_00020',  N'PMM_00001'), 
(N'PMM_00220',  N'PMM_00020') 

;WITH ClassHierarchy_CTE (ClassID, ClassID_Join, Level) 
AS 
(
SELECT 
    ClassID, 
    ClassID AS Join_Class, 
    0 
FROM 
    hierarchy AS c 
UNION ALL 
SELECT 
    cte.ClassID, 
    h.ParentID, 
    Level + 1 
FROM 
    hierarchy AS h INNER JOIN ClassHierarchy_CTE as cte 
     ON 
     h.ClassID = cte.ClassID_Join 
) 
SELECT 
    * 
FROM 
    ClassHierarchy_CTE 
WHERE 
    ClassID_Join IS NOT NULL 
ORDER BY 
    ClassID, 
    Level 

返回...

CLASSID CLASSID_JOIN LEVEL 
--------------------------------- 
PMM_00001 PMM_00001 0 
PMM_00010 PMM_00010 0 
PMM_00010 PMM_00001 1 
PMM_00020 PMM_00020 0 
PMM_00020 PMM_00001 1 
PMM_00110 PMM_00110 0 
PMM_00110 PMM_00010 1 
PMM_00110 PMM_00001 2 
PMM_00220 PMM_00220 0 
PMM_00220 PMM_00020 1 
PMM_00220 PMM_00001 2 

SQLfiddle以供參考。