2010-04-29 5 views
7

Sur la base d'une table existante, j'ai utilisé la requête récursive CTE pour trouver les données suivantes. Mais ne pas l'appliquer un niveau plus loin.Requête récursive t-sql

données est comme ci-dessous

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 

Je veux former récursive chemins complets à partir des données ci-dessus. Signifie que la récursivité donnera la sortie suivante.

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 

Merci

Répondre

4

Voici un exemple CTE à faire:

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

Quelque chose comme

;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

essayez ceci:

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 

sortie:

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

Essayez quelque chose comme ceci:

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 

Sortie:

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

Vous devez changer le nom de la table #test j'utilisais.

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