2012-11-15 32 views
2

親愛#1構件T-SQL遞歸CTE,需要長的路徑縮短結果

我有一個遞歸CTE查詢這樣的:

DECLARE @Level TABLE (ID int, ParentID int, Name varchar(max)) 

INSERT INTO @Level (ID, ParentID, Name) 
     VALUES (1,0, 'AAAA'), 
       (2,1, 'BBBB'), 
       (3,2, 'CCCC'), 
       (4,3, 'DDDD'), 
       (5,4, 'EEEE') 

;WITH cte (ID, ParentID, Name, Path, Level) AS 
(
    SELECT 
     ID, ParentID, Name, CONVERT(varchar(MAX), Name), 1 
    FROM 
     @Level 
    WHERE 
     ParentID = 0 

    UNION ALL 

    SELECT 
     n.ID, n.ParentID, n.Name, 
     CONVERT(varchar(MAX), cte.Path + '/' + n.Name), cte.Level + 1 
    FROM 
     @Level n 
    JOIN 
     cte on n.ParentID = cte.ID 
    ) 
    SELECT * FROM cte 

從上述查詢結果:

ID   ParentID Name Path       Level 
----------- ----------- ------- ---------------------------- ----------- 
1   0   AAAA AAAA       1 
2   1   BBBB AAAA/BBBB     2 
3   2   CCCC AAAA/BBBB/CCCC    3 
4   3   DDDD AAAA/BBBB/CCCC/DDDD   4 
5   4   EEEE AAAA/BBBB/CCCC/DDDD/EEEE  5 

CTE查詢所需的輸出:

ID   ParentID Name Paths      Path       Level 
----------- ----------- ----------------------------------- ---------------------------- ----------- 
1   0   AAAA AAAA       AAAA       1 
2   1   BBBB AAAA/BBBB     AAAA/BBBB     2 
3   2   CCCC AAAA/.../CCCC    AAAA/BBBB/CCCC    3 
4   3   DDDD AAAA/.../.../DDDD   AAAA/BBBB/CCCC/DDDD   4 
5   4   EEEE AAAA/.../.../.../EEEE  AAAA/BBBB/CCCC/DDDD/EEEE  5 

從上面的例子可以看出,路徑可能會變得很長,並且寧願將路徑替換爲點。除了開始和結束字符保持可見並且只有中間內容被替換之外。請注意,VALUES的內容可以是任何僅用作示例的內容。

感謝

回答

3

這種摺疊所有除root和當前

DECLARE @Level TABLE (ID int, ParentID int, Name varchar(max)) 

     INSERT INTO @Level (ID, ParentID, Name) 
     VALUES (1,0, 'AAAA'), 
       (2,1, 'BBBB'), 
       (3,2, 'CCCC'), 
       (4,3, 'DDDD'), 
       (5,4, 'EEEE') 


     ;WITH cte (ID, ParentID, Name, Root, Path, Level) AS 
    (
    SELECT ID, ParentID, Name, CONVERT(varchar(MAX), Name), 
      CONVERT(varchar(MAX), Name), 1 
    FROM @Level 
    WHERE ParentID = 0 
    UNION ALL 
    SELECT n.ID, n.ParentID, n.Name, cte.Root, cte.Root + '/' + 
      CASE WHEN cte.Level=1 then '' 
       else replicate('.../', cte.level-1) end + 
      n.Name, cte.Level + 1 
    FROM @Level n 
    JOIN cte on n.ParentID = cte.ID 
    ) 
    SELECT * FROM cte