2010-04-29 45 views
7

Dựa trên bảng hiện có, tôi đã sử dụng truy vấn đệ quy CTE để tìm ra dữ liệu sau. Nhưng không áp dụng nó một cấp độ cao hơn.truy vấn đệ quy t-sql

dữ liệu là như sau

id name  parentid 
-------------------------- 
1  project 0 
2  structure 1 
3  path_1 2 
4  path_2 2 
5  path_3 2 
6  path_4 3 
7  path_5 4 
8  path_6 5 

Tôi muốn đệ quy thành đường dẫn đầy đủ từ các dữ liệu trên. Có nghĩa là đệ quy sẽ cung cấp cho đầu ra sau.

FullPaths 
------------- 
Project 
Project\Structure 
Project\Structure\Path_1 
Project\Structure\Path_2 
Project\Structure\Path_3 
Project\Structure\Path_1\path_4 
Project\Structure\Path_2\path_5 
Project\Structure\Path_3\path_6 

Cảm ơn

Trả lời

4

Dưới đây là một ví dụ CTE để làm điều đó:

declare @t table (id int, name varchar(max), parentid int) 

insert into @t select 1,  'project' , 0 
union all select 2,  'structure' , 1 
union all select 3,  'path_1' , 2 
union all select 4,  'path_2' , 2 
union all select 5,  'path_3' , 2 
union all select 6,  'path_4' , 3 
union all select 7,  'path_5' , 4 
union all select 8,  'path_6' , 5 

; with CteAlias as (
    select id, name, parentid 
    from @t t 
    where t.parentid = 0 
    union all 
    select t.id, parent.name + '\' + t.name, t.parentid 
    from @t t 
    inner join CteAlias parent on t.parentid = parent.id 
) 
select * 
from CteAlias 
0

Something như

;WITH MyCTE AS 
(
    SELECT 
     name AS FullPaths, id 
    FROM 
     MyTable 
    WHERE 
     parentid = 0 /*Normally it'd be IS NULL with an FK linking the 2 columns*/ 
    UNION ALL 
    SELECT 
     C.FullPaths + '\' + M.name, M.id 
    FROM 
     MyCTE C 
     JOIN 
     MyTable M ON M.parentid = C.id 
) 
SELECT FullPaths FROM MyCTE 
0

thử điều này:

DECLARE @YourTable table (id int, nameof varchar(25), parentid int) 
INSERT @YourTable VALUES (1,'project',0) 
INSERT @YourTable VALUES (2,'structure',1) 
INSERT @YourTable VALUES (3,'path_1',2) 
INSERT @YourTable VALUES (4,'path_2',2) 
INSERT @YourTable VALUES (5,'path_3',2) 
INSERT @YourTable VALUES (6,'path_4',3) 
INSERT @YourTable VALUES (7,'path_5',4) 
INSERT @YourTable VALUES (8,'path_6',5) 

;WITH Rec AS 
(
    SELECT 
     CONVERT(varchar(max),nameof) as nameof,id 
     FROM @YourTable 
     WHERE parentid=0 
    UNION ALL 
    SELECT 
     CONVERT(varchar(max),r.nameof+'\'+y.nameof), y.id 
     FROM @yourTable y 
      INNER jOIN Rec r ON y.parentid=r.id 
) 
select * from rec 

đầu ra:

nameof           
----------------------------------------------- 
project           
project\structure        
project\structure\path_1      
project\structure\path_2      
project\structure\path_3      
project\structure\path_3\path_6     
project\structure\path_2\path_5     
project\structure\path_1\path_4     

(8 row(s) affected) 
3

Hãy thử một cái gì đó như thế này:

WITH Recursive AS 
(
    SELECT 
     ID, 
      CAST(PathName AS VARCHAR(500)) AS 'FullPaths', 
      1 AS 'Level' 
    FROM 
     dbo.YourTable 
    WHERE 
     ParentID = 0 

    UNION ALL 

    SELECT 
     tbl.ID, 
      CAST(r.FullPaths + '\' + tbl.PathName AS VARCHAR(500)) AS 'FullPaths', 
      r.Level + 1 AS 'Level' 
    FROM 
     dbo.YourTable tbl 
    INNER JOIN 
     Recursive r ON tbl.ParentID = r.ID 
) 
SELECT * FROM Recursive 
ORDER BY Level, ID 

Output:

ID FullPaths     Level 
1 project       1 
2 project\structure     2 
3 project\structure\path_1   3 
4 project\structure\path_2   3 
5 project\structure\path_3   3 
6 project\structure\path_1\path_4 4 
7 project\structure\path_2\path_5 4 
8 project\structure\path_3\path_6 4 
0

Bạn sẽ phải thay đổi tên của bảng #test Tôi đã sử dụng.

WITH cte(id, name, parentid) AS 
(
    SELECT id, convert(varchar(128), name), parentid 
    FROM #test 
    WHERE parentid = 0 
    UNION ALL 
    SELECT t.id, convert(varchar(128), c.name +'\'+t.name), t.parentid 
    FROM #test t 
    INNER JOIN cte c 
    ON c.id = t.parentid 
) 
SELECT name as FullPaths 
FROM cte 
order by id 
Các vấn đề liên quan