2010-06-17 37 views
0

我想獲得遞歸數據。 以下代碼返回頂部的所有父母,然後返回孩子。 我想獲取數據家長1 - 他的孩子然後是家長2 - 他的孩子然後是家長3 - 他的孩子。 我該怎麼做?獲取與sql服務器的遞歸數據

USE Subscriber 
GO 
WITH Parent (ParentId, Id, Name,subscriberID) 
AS 
(
-- Anchor member definition 
    SELECT A.ParentId,A.id, A.name,A.SubscriberId 

    FROM Subscriber.Budget.SubscriberCategory AS A 
    WHERE ParentId IS NULL 
    UNION ALL 
-- Recursive member definition 
    SELECT B.ParentId, B.id, B.name,B.SubscriberId 

    FROM Subscriber.Budget.SubscriberCategory AS B 

    INNER JOIN Parent AS P 


ON B.ParentId = P.Id 
) 

-- Statement that executes the CTE 
SELECT parentId, id, name 
FROM Parent 
where subscriberID = '1C18093B-5031-42E4-9251-CEF69114365F' 

GO 
+1

如何添加一些TSQL創建並填充一些測試數據,還有預期的結果集? – 2010-06-17 15:08:32

回答

1

這裏是一個通用的解決方案,該OP可以映射到自己的表/列:

建立數據

DECLARE @Staff table (UserID char(4), UserName varchar(10), ManagerID char(4)) 
INSERT @Staff VALUES ('ABC1','Jerome', NULL) 
INSERT @Staff VALUES ('ABC2','Joe' ,'ABC1') 
INSERT @Staff VALUES ('ABC3','Paul' ,'ABC2') 
INSERT @Staff VALUES ('ABC4','Jack' ,'ABC3') 
INSERT @Staff VALUES ('ABC5','Daniel','ABC3') 
INSERT @Staff VALUES ('ABC6','David' ,'ABC2') 
INSERT @Staff VALUES ('ABC7','Ian' ,'ABC6') 
INSERT @Staff VALUES ('ABC8','Helen' ,'ABC6') 
INSERT @Staff VALUES ('ABC9','Sam' , NULL) 
INSERT @Staff VALUES ('ABD1','Ron' ,'ABC9') 
INSERT @Staff VALUES ('ABD2','Bill' ,'ABC9') 
INSERT @Staff VALUES ('ABD3','Fred' ,'ABD1') 

DECLARE @RootUserID char(4) 
SET @RootUserID='ABC2' 

得到完整的樹

;WITH StaffTree AS 
(
    SELECT 
     UserID, UserName, ManagerID, CONVERT(char(4),NULL) AS ManagerUserID, 1 AS LevelOf 
      ,CONVERT(varchar(max),UserID) AS ChainOfCommand 
     FROM @Staff 
     WHERE ManagerID IS NULL 
    UNION ALL 
     SELECT 
      s.UserID, s.UserName, s.ManagerID, t.UserID, t.LevelOf+1 
       ,ISNULL(t.ChainOfCommand,'')+'|'+s.ManagerID 
     FROM StaffTree   t 
      INNER JOIN @Staff s ON t.UserID=s.ManagerID 

) 
SELECT * FROM StaffTree ORDER BY ChainOfCommand,UserID 

獲取樹給用戶

;WITH StaffTree AS 
(
    SELECT 
     UserID, UserName, ManagerID, CONVERT(char(4),NULL) AS ManagerUserID, 1 AS LevelOf 
      ,CONVERT(varchar(max),UserID) AS ChainOfCommand 
     FROM @Staff 
     WHERE [email protected] 
    UNION ALL 
     SELECT 
      s.UserID, s.UserName, s.ManagerID, t.UserID, t.LevelOf+1 
       ,ISNULL(t.ChainOfCommand,'')+'|'+s.ManagerID 
     FROM StaffTree   t 
      INNER JOIN @Staff s ON t.UserID=s.ManagerID 
     WHERE [email protected] 

) 
SELECT * FROM StaffTree ORDER BY ChainOfCommand,UserID 

OUTPUT:

UserID UserName ManagerID ManagerUserID LevelOf  ChainOfCommand 
------ ---------- --------- ------------- ----------- ------------------------ 
ABC1 Jerome  NULL  NULL   1   ABC1 
ABC2 Joe  ABC1  ABC1   2   ABC1|ABC1 
ABC3 Paul  ABC2  ABC2   3   ABC1|ABC1|ABC2 
ABC6 David  ABC2  ABC2   3   ABC1|ABC1|ABC2 
ABC4 Jack  ABC3  ABC3   4   ABC1|ABC1|ABC2|ABC3 
ABC5 Daniel  ABC3  ABC3   4   ABC1|ABC1|ABC2|ABC3 
ABC7 Ian  ABC6  ABC6   4   ABC1|ABC1|ABC2|ABC6 
ABC8 Helen  ABC6  ABC6   4   ABC1|ABC1|ABC2|ABC6 
ABC9 Sam  NULL  NULL   1   ABC9 
ABD1 Ron  ABC9  ABC9   2   ABC9|ABC9 
ABD2 Bill  ABC9  ABC9   2   ABC9|ABC9 
ABD3 Fred  ABD1  ABD1   3   ABC9|ABC9|ABD1 

(12 row(s) affected) 

UserID UserName ManagerID ManagerUserID LevelOf  ChainOfCommand 
------ ---------- --------- ------------- ----------- ------------------------ 
ABC2 Joe  ABC1  NULL   1   ABC2 
ABC3 Paul  ABC2  ABC2   2   ABC2|ABC2 
ABC6 David  ABC2  ABC2   2   ABC2|ABC2 

(3 row(s) affected) 

編輯上面的代碼基本編輯使用唯一標識符標識:

DECLARE @Staff table (UserID uniqueidentifier, UserName varchar(10), ManagerID uniqueidentifier) 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B0D','Jerome', NULL) 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B02','Joe' ,'6A3BEB4C-D116-481E-B98D-4779246C4B0D') 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B03','Paul' ,'6A3BEB4C-D116-481E-B98D-4779246C4B02') 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B04','Jack' ,'6A3BEB4C-D116-481E-B98D-4779246C4B03') 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B05','Daniel','6A3BEB4C-D116-481E-B98D-4779246C4B03') 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B06','David' ,'6A3BEB4C-D116-481E-B98D-4779246C4B02') 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B07','Ian' ,'6A3BEB4C-D116-481E-B98D-4779246C4B06') 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B08','Helen' ,'6A3BEB4C-D116-481E-B98D-4779246C4B06') 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B09','Sam' , NULL) 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B11','Ron' ,'6A3BEB4C-D116-481E-B98D-4779246C4B09') 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B12','Bill' ,'6A3BEB4C-D116-481E-B98D-4779246C4B09') 
INSERT @Staff VALUES ('6A3BEB4C-D116-481E-B98D-4779246C4B13','Fred' ,'6A3BEB4C-D116-481E-B98D-4779246C4B11') 


DECLARE @RootUserID char(4) 
SET @RootUserID='6A3BEB4C-D116-481E-B98D-4779246C4B02' 

;WITH StaffTree AS 
(
    SELECT 
     UserID, UserName, ManagerID, CONVERT(uniqueidentifier,NULL) AS ManagerUserID, 1 AS LevelOf 
      ,CONVERT(varchar(max),UserID) AS ChainOfCommand 
     FROM @Staff 
     WHERE ManagerID IS NULL 
    UNION ALL 
     SELECT 
      s.UserID, s.UserName, s.ManagerID, t.UserID, t.LevelOf+1 
       ,ISNULL(t.ChainOfCommand,'')+'|'+CONVERT(varchar(max),s.ManagerID) 
     FROM StaffTree   t 
      INNER JOIN @Staff s ON t.UserID=s.ManagerID 

) 
SELECT * FROM StaffTree ORDER BY ChainOfCommand,UserID 

OUTPUT:

UserID        UserName ManagerID       ManagerUserID      LevelOf  ChainOfCommand 
------------------------------------ ---------- ------------------------------------ ------------------------------------ ----------- ---------------------------------------------------------------------------------------------------------------------------------------------------- 
6A3BEB4C-D116-481E-B98D-4779246C4B09 Sam  NULL         NULL         1   6A3BEB4C-D116-481E-B98D-4779246C4B09 
6A3BEB4C-D116-481E-B98D-4779246C4B11 Ron  6A3BEB4C-D116-481E-B98D-4779246C4B09 6A3BEB4C-D116-481E-B98D-4779246C4B09 2   6A3BEB4C-D116-481E-B98D-4779246C4B09|6A3BEB4C-D116-481E-B98D-4779246C4B09 
6A3BEB4C-D116-481E-B98D-4779246C4B12 Bill  6A3BEB4C-D116-481E-B98D-4779246C4B09 6A3BEB4C-D116-481E-B98D-4779246C4B09 2   6A3BEB4C-D116-481E-B98D-4779246C4B09|6A3BEB4C-D116-481E-B98D-4779246C4B09 
6A3BEB4C-D116-481E-B98D-4779246C4B13 Fred  6A3BEB4C-D116-481E-B98D-4779246C4B11 6A3BEB4C-D116-481E-B98D-4779246C4B11 3   6A3BEB4C-D116-481E-B98D-4779246C4B09|6A3BEB4C-D116-481E-B98D-4779246C4B09|6A3BEB4C-D116-481E-B98D-4779246C4B11 
6A3BEB4C-D116-481E-B98D-4779246C4B0D Jerome  NULL         NULL         1   6A3BEB4C-D116-481E-B98D-4779246C4B0D 
6A3BEB4C-D116-481E-B98D-4779246C4B02 Joe  6A3BEB4C-D116-481E-B98D-4779246C4B0D 6A3BEB4C-D116-481E-B98D-4779246C4B0D 2   6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B0D 
6A3BEB4C-D116-481E-B98D-4779246C4B03 Paul  6A3BEB4C-D116-481E-B98D-4779246C4B02 6A3BEB4C-D116-481E-B98D-4779246C4B02 3   6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B02 
6A3BEB4C-D116-481E-B98D-4779246C4B06 David  6A3BEB4C-D116-481E-B98D-4779246C4B02 6A3BEB4C-D116-481E-B98D-4779246C4B02 3   6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B02 
6A3BEB4C-D116-481E-B98D-4779246C4B04 Jack  6A3BEB4C-D116-481E-B98D-4779246C4B03 6A3BEB4C-D116-481E-B98D-4779246C4B03 4   6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B02|6A3BEB4C-D116-481E-B98D-4779246C4B03 
6A3BEB4C-D116-481E-B98D-4779246C4B05 Daniel  6A3BEB4C-D116-481E-B98D-4779246C4B03 6A3BEB4C-D116-481E-B98D-4779246C4B03 4   6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B02|6A3BEB4C-D116-481E-B98D-4779246C4B03 
6A3BEB4C-D116-481E-B98D-4779246C4B07 Ian  6A3BEB4C-D116-481E-B98D-4779246C4B06 6A3BEB4C-D116-481E-B98D-4779246C4B06 4   6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B02|6A3BEB4C-D116-481E-B98D-4779246C4B06 
6A3BEB4C-D116-481E-B98D-4779246C4B08 Helen  6A3BEB4C-D116-481E-B98D-4779246C4B06 6A3BEB4C-D116-481E-B98D-4779246C4B06 4   6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B0D|6A3BEB4C-D116-481E-B98D-4779246C4B02|6A3BEB4C-D116-481E-B98D-4779246C4B06 

(12 row(s) affected) 
+0

我的Id和parentID id都是uniqueidentifier字段,我得到以下錯誤。 Msg 291,Level 16,State 1,Line 5 CAST或CONVERT:爲'uniqueidentifier'類型指定的無效屬性 – user228777 2010-06-17 17:19:29

+0

@ user228777,請參閱編輯 – 2010-06-17 17:45:54

+0

+1。遠遠勝過遊標。但是,那麼,我認爲遊標是由撒旦發明的...... – AllenG 2010-06-17 17:49:47

0

看看光標Here

我個人不喜歡他們,但我可以避免他們,但它會給你一種方法,一次抓住一個父母,然後是所有父母的孩子。

+0

正如你所說Curser將是我的最後一個選擇,我想嘗試以上的解決方案,看起來它會工作。 感謝您的回覆。 – user228777 2010-06-17 17:20:18