Voulez-vous connaître toutes les lignes parent et enfant possibles par rapport à un identifiant spécifique?

Comment connaître toutes les lignes parent et enfant possibles par rapport à un identifiant spécifique?

par exemple avoir le tableau suivant:

Ma table:

----------------------------------------------------- | Id | PId | Description | ----------------------------------------------------- | 1 | NULL | A is Parent | | 2 | 1 | B is Child of A | | 3 | 2 | C is Child of B | | 4 | NULL | D is Parent | | 5 | NULL | E is Parent | | 6 | 5 | F is Child of E | ----------------------------------------------------- 

veulent connaître tous les parents et enfants possibles lorsqu'ils transmettent un identifiant spécifique

par exemple

CAS-01:

Quand @ MyLookupId = 2 OU @ MyLookupId = 1 OU @ MyLookupId = 3 L'un d'entre eux alors le résultat devrait être,

 ------- | Id | ------- | 1 | | 2 | | 3 | ------- 

CAS-02:

Quand @ MyLookupId = 4 alors le résultat devrait être,

 ------- | Id | ------- | 4 | ------- 

CAS-03:

Quand @ MyLookupId = 6 alors le résultat devrait être,

 ------- | Id | ------- | 5 | | 6 | ------- 

Voici SQL pour la table:

 IF OBJECT_ID('tempdb.dbo.#MyTable', 'U') IS NOT NULL DROP TABLE #MyTable; SELECT * INTO #MyTable FROM ( SELECT (1)Id, (NULL)PId, ('A IS Parent')Description UNION ALL SELECT (2)Id, (1)PId, ('B IS Child of A')Description UNION ALL SELECT (3)Id, (2)PId, ('C IS Child of B')Description UNION ALL SELECT (4)Id, (NULL)PId, ('D IS Parent')Description UNION ALL SELECT (5)Id, (NULL)PId, ('E IS Parent')Description UNION ALL SELECT (6)Id, (5)PId, ('F IS Child of E')Description ) AS tmp SELECT * FROM #MyTable 

La réponse fournie par TriV fonctionne, mais nécessite un calcul de la hiérarchie entière de votre table source chaque fois que la requête est exécutée, ce qui peut ne pas fonctionner correctement à plus grande échelle.

Une approche plus étroite consiste à find les loggings Parent et Enfant qui se rapportent uniquement à l' ID vous searchz:

 declare @t table(ID int, PID int); insert into @t values(1,null),(2,1),(3,2),(4,null),(5,null),(6,5); declare @ID int = 2; with c as ( select ID ,PID from @t where ID = @ID union all select t.ID ,t.PID from @tt join c on(t.PID = c.ID) ) ,p as ( select ID ,PID from @t where ID = @ID union all select t.ID ,t.PID from @tt join p on(t.ID = p.PID) ) select ID from p union all select ID from c where c.ID <> @ID order by ID; 

Sortie:

  ID ```` 1 2 3 

Vous pouvez utiliser recursive cte

 -- temp returns full tree of each rootId (parentid = null) ;WITH temp AS ( SELECT sd.Id, sd.PId, sd.Id AS RootId FROM #MyTable sd WHERE sd.PId IS NULL UNION ALL SELECT sd.Id, sd.PId, t.RootId FROM temp t INNER JOIN #MyTable sd ON t.Id = sd.PId ) SELECT t2.Id FROM temp t INNER JOIN temp t2 ON t2.RootId = t.RootId WHERE t.Id = @Id OPTION (MAXRECURSION 0) 

Lien de démonstration: http://rextester.com/RAITMT72805