Liste adjacente et requête récursive utilisant un CTE, comment remplir?

J'ai une requête qui produit une hiérarchie aplatie à partir d'une table parent-enfant (auto-jointure, list adjacente). Le problème est que cette requête produit des valeurs NULL pour les niveaux qui n'ont aucun enfant. Maintenant, mon intention est de «remplir» ces niveaux pour produire une table qui ne contient aucune valeur NULL dans les colonnes de niveau. Comment dois-je modifier cette requête?

Exemple de données:

SET NOCOUNT ON; USE Tempdb; IF OBJECT_ID('dbo.Employees', 'U') IS NOT NULL DROP TABLE dbo.Employees; CREATE TABLE dbo.Employees ( empid INT NOT NULL PRIMARY KEY, mgrid INT NULL REFERENCES dbo.Employees, empname VARCHAR(25) NOT NULL, salary MONEY NOT NULL, CHECK (empid <> mgrid), CHECK (empid > 0) ); CREATE UNIQUE INDEX idx_unc_mgrid_empid ON dbo.Employees(mgrid, empid); INSERT INTO dbo.Employees(empid, mgrid, empname, salary) VALUES (1, NULL, 'David' , $10000.00), (2, 1, 'Eitan' , $7000.00), (3, 1, 'Ina' , $7500.00), (4, 2, 'Seraph' , $5000.00), (5, 2, 'Jiru' , $5500.00), (6, 2, 'Steve' , $4500.00), (7, 3, 'Aaron' , $5000.00), (8, 5, 'Lilach' , $3500.00), (9, 7, 'Rita' , $3000.00), (10, 5, 'Sean' , $3000.00), (11, 7, 'Gabriel', $3000.00), (12, 9, 'Emilia' , $2000.00), (13, 9, 'Michael', $2000.00), (14, 9, 'Didi' , $1500.00); 

requête fournie par @Andomar

 ; with Tree as ( SELECT empid , mgrid , 1 as lv , 1 as level1 , null as level2 , null as level3 , null as level4 , null as level5 FROM Employees WHERE mgrid IS NULL UNION ALL SELECT E.empid , E.mgrid , T.lv + 1 , T.level1 , case when T.lv = 1 then E.empid else t.level2 end , case when T.lv = 2 then E.empid else t.level3 end , case when T.lv = 3 then E.empid else t.level4 end , case when T.lv = 4 then E.empid else t.level5 end FROM Employees AS E JOIN Tree T ON E.mgrid = T.empid ) select * from Tree order by empid 

Cela donne

 +-------+--------+----+--------+--------+--------+--------+--------+ | EMPID | MGRID | LV | LEVEL1 | LEVEL2 | LEVEL3 | LEVEL4 | LEVEL5 | +-------+--------+----+--------+--------+--------+--------+--------+ | 1 | (null) | 1 | 1 | (null) | (null) | (null) | (null) | | 2 | 1 | 2 | 1 | 2 | (null) | (null) | (null) | | 3 | 1 | 2 | 1 | 3 | (null) | (null) | (null) | | 4 | 2 | 3 | 1 | 2 | 4 | (null) | (null) | | 5 | 2 | 3 | 1 | 2 | 5 | (null) | (null) | | 6 | 2 | 3 | 1 | 2 | 6 | (null) | (null) | | 7 | 3 | 3 | 1 | 3 | 7 | (null) | (null) | | 8 | 5 | 4 | 1 | 2 | 5 | 8 | (null) | | 9 | 7 | 4 | 1 | 3 | 7 | 9 | (null) | | 10 | 5 | 4 | 1 | 2 | 5 | 10 | (null) | | 11 | 7 | 4 | 1 | 3 | 7 | 11 | (null) | | 12 | 9 | 5 | 1 | 3 | 7 | 9 | 12 | | 13 | 9 | 5 | 1 | 3 | 7 | 9 | 13 | | 14 | 9 | 5 | 1 | 3 | 7 | 9 | 14 | +-------+--------+----+--------+--------+--------+--------+--------+ 

mais l'idée est de réaliser cela

 +-------+--------+----+--------+--------+--------+--------+--------+ | EMPID | MGRID | LV | LEVEL1 | LEVEL2 | LEVEL3 | LEVEL4 | LEVEL5 | +-------+--------+----+--------+--------+--------+--------+--------+ | 1 | (null) | 1 | 1 | 1 | 1 | 1 | 1 | | 2 | 1 | 2 | 1 | 2 | 2 | 2 | 2 | | 3 | 1 | 2 | 1 | 3 | 3 | 3 | 3 | | 4 | 2 | 3 | 1 | 2 | 4 | 4 | 4 | | 5 | 2 | 3 | 1 | 2 | 5 | 5 | 5 | | 6 | 2 | 3 | 1 | 2 | 6 | 6 | 6 | | 7 | 3 | 3 | 1 | 3 | 7 | 7 | 7 | | 8 | 5 | 4 | 1 | 2 | 5 | 8 | 8 | | 9 | 7 | 4 | 1 | 3 | 7 | 9 | 9 | | 10 | 5 | 4 | 1 | 2 | 5 | 10 | 10 | | 11 | 7 | 4 | 1 | 3 | 7 | 11 | 11 | | 12 | 9 | 5 | 1 | 3 | 7 | 9 | 12 | | 13 | 9 | 5 | 1 | 3 | 7 | 9 | 13 | | 14 | 9 | 5 | 1 | 3 | 7 | 9 | 14 | +-------+--------+----+--------+--------+--------+--------+--------+ 

    Ajoutez juste ci-dessous après l'tree CTE

     Select empid,mgrid,lv, level1 = coalesce(level1,Rn), level2 = coalesce(level2,Rn), level3 = coalesce(level3,Rn), level4 = coalesce(level4,Rn), level5 = coalesce(level5,Rn) from (select empid,mgrid,lv,level1,level2,level3,level4,level5,Row_Number()Over(Order By empid) as Rn from Tree)x 

    entrez la description de l'image ici

    juste un simple essai de modifier les résultats comme vous le souhaitez serait d'utiliser coalesce() dans le dernier select.

    voir sql-fiddle ici

    J'ai trouvé cela aussi:

     ; with Tree as ( SELECT empid , mgrid , 1 as lv , 1 as level1 , null as level2 , null as level3 , null as level4 , null as level5 FROM Employees WHERE mgrid IS NULL UNION ALL SELECT E.empid , E.mgrid , T.lv + 1 , T.level1 , case when T.lv = 1 then E.empid else t.level2 end , case when T.lv = 2 then E.empid else t.level3 end , case when T.lv = 3 then E.empid else t.level4 end , case when T.lv = 4 then E.empid else t.level5 end FROM Employees AS E JOIN Tree T ON E.mgrid = T.empid ) select empid, mgrid, lv, level1, level2 = coalesce(level2, level1), level3 = coalesce(level3, level2, level1), level4 = coalesce(level4, level3, level2, level1), level5 = coalesce(level5, level4, level3, level2, level1) from Tree order by empid