Déclaration de cas complexe T-SQL – avec traversée hiérarchique.

J'essaie d'écrire une instruction CASE complexe sur un set de données hiérarchique.

Voici le tableau avec des exemples de données:

 Level Parent Child IsDirector ---------------------------------------- 0 NULL SteveJobs NO 1 SteveJobs TimCook YES 2 TimCook Greg NO 3 Greg Mark NO 4 Mark Jack NO 4 Mark Kim NO 4 Mark Tyler NO 4 Mark Emma NO 

J'essaye d'écrire une requête SQL pour listr le directeur pour toutes les personnes. Dans l'exemple ci-dessus, cette partie d'une équipe informatique où SteveJobs est le PDG et donc il n'est pas un directeur. TimCook est le directeur et sous le directeur est le gestionnaire Greg. Sous le gestionnaire sont les employés.

Donc, je veux écrire une requête pour sélectionner toutes les personnes et le nom du directeur associé dans la colonne Directeur avec une condition où si c'est un chef de la direction alors il devrait être NULL.

Dans mes données réelles, il y a plusieurs PDG et il y aura plusieurs administrateurs sous chaque PDG et plusieurs directeurs sous chaque directeur. C'est vraiment compliqué pour moi.

Le résultat est supposé être comme ceci si j'écris un select *.

 Parent Child Director IsDirector ------------------------------------ NULL SteveJobs NULL NO SteveJobs TimCook TimCook YES TimCook Greg TimCook NO Greg Mark TimCook NO Mark Jack TimCook NO Mark Kim TimCook NO Mark Tyler TimCook NO Mark Emma TimCook NO 

Et voici la requête que j'ai écrite pour y parvenir, mais cela ne fonctionne pas comme prévu.

 SELECT A.Parent, A.Child, CASE A.IsDirector WHEN 'YES' THEN A.Child WHEN 'NO' THEN CASE WHEN (A.IsDirector = 'NO' AND A.Parent IS NOT NULL) THEN A.Parent ELSE (SELECT CASE WHEN B.IsDirector = 'YES' THEN B.Parent END AS Director FROM @Org B WHERE B.Child = A.Parent) END END AS Director, A.IsDirector FROM @Org A 

Cela peut être généré à l'aide d'un cte récursif

 Declare @YourTable table (Level int,Parent varchar(50),Child varchar(50),IsDirector varchar(50)) Insert into @YourTable values (0,NULL,'SteveJobs','NO'), (1,'SteveJobs','TimCook','YES'), (2,'TimCook','Greg','NO'), (3,'Greg','Mark','NO'), (4,'Mark','Jack','NO'), (4,'Mark','Kim','NO'), (4,'Mark','Tyler','NO'), (4,'Mark','Emma','NO') ;with cteP as ( Select Parent ,Child ,Director = case when IsDirector='YES' then CHILD else NULL end ,IsDirector From @YourTable Where Parent is null Union All Select r.Parent ,r.Child ,Director = case when r.IsDirector='YES' then r.CHILD else p.Director end ,r.IsDirector From @YourTable r Join cteP p on r.Parent = p.Child) Select * from cteP 

Résultats

entrez la description de l'image ici

 DECLARE @Table AS TABLE (Level INT, Parent VARCHAR(100), Child VARCHAR(100), IsDirector VARCHAR(3)) INSERT INTO @Table VALUES (0,NULL,'SteveJobs','NO') ,(1,'SteveJobs','TimCook','YES') ,(2,'TimCook','Greg','NO') ,(3,'Greg','Mark','NO') ,(4,'Mark','Jack','NO') ,(4,'Mark','Kim','NO') ,(4,'Mark','Tyler','NO') ,(4,'Mark','Emma','NO') ;WITH cte AS ( SELECT CEO = t.Child ,t.Parent ,t.Child ,Director = CASE WHEN t.IsDirector = 'YES' THEN t.Child ELSE NULL END ,t.IsDirector FROM @Table t WHERE t.Parent IS NULL UNION ALL SELECT c.CEO ,t.Parent ,t.Child ,Director = CASE WHEN t.IsDirector = 'YES' THEN t.Child ELSE c.Director END ,t.IsDirector FROM @Table t INNER JOIN cte c ON c.Child = t.Parent ) SELECT * FROM cte 

En voyant que vous connaissez le PDG (Parent = NULL), commencez votre recursion depuis le haut et descendez.