SQL Obtention de toutes les lignes associées

J'ai essayé de comprendre (très lentement) au cours des deux dernières semaines comment find une meilleure façon d'interroger toutes les lignes liées à un ID. Mon entreprise est dans une situation où une marque est renommée et nous n'avons pas la possibilité de modifier les loggings précédents (dans quelques autres arrays) qui pointent vers la marque qui a été remplacée.

J'ai fait une petite version de ma table pour aider les gens à vérifier:

CREATE TABLE #GrwHist ( ID INT , Acronym VARCHAR(50) , New_ID INT ) INSERT INTO #GrwHist VALUES(1,'ABC',33) INSERT INTO #GrwHist VALUES(21,'GST',NULL) INSERT INTO #GrwHist VALUES(33,'MnY',48) INSERT INTO #GrwHist VALUES(37,'FWR',89) INSERT INTO #GrwHist VALUES(48,'DMZ',89) INSERT INTO #GrwHist VALUES(89,'PLT',106) INSERT INTO #GrwHist VALUES(106,'TnI',NULL) INSERT INTO #GrwHist VALUES(120,'YIZ',143) INSERT INTO #GrwHist VALUES(143,'INZ',NULL) SELECT * FROM #GrwHist /* ID Acronym New_ID --- ------- ------- 1 ABC 33 21 GST NULL 33 MnY 48 37 FWR 89 48 DMZ 89 89 PLT 106 106 TnI NULL 120 YIZ 143 143 INZ NULL */ DECLARE @ID INT SET @ID = 106 SELECT * FROM #GrwHist WHERE ID = @ID UNION SELECT * FROM #GrwHist WHERE New_ID in (@ID) UNION SELECT * FROM #GrwHist WHERE New_ID in (SELECT ID FROM #GrwHist WHERE New_ID in (@ID)) UNION SELECT * FROM #GrwHist WHERE New_ID in ( SELECT ID FROM #GrwHist WHERE New_ID in (SELECT ID FROM #GrwHist WHERE New_ID in (@ID)) ) UNION SELECT * FROM #GrwHist WHERE New_ID in ( SELECT ID FROM #GrwHist WHERE New_ID in (SELECT ID FROM #GrwHist WHERE New_ID in (SELECT ID FROM #GrwHist WHERE New_ID in (@ID))) ) UNION SELECT * FROM #GrwHist WHERE New_ID in ( SELECT ID FROM #GrwHist WHERE New_ID in (SELECT ID FROM #GrwHist WHERE New_ID in (SELECT ID FROM #GrwHist WHERE New_ID in (SELECT ID FROM #GrwHist WHERE New_ID in (@ID)))) ) --And it grows and grows... GO DROP TABLE #GrwHist 

La dernière requête est essentiellement pour:

 --If I need to get all IDs related to a given ID I will get the following results: @ID = 106 --> 106, 89, 48, 37, 33, 1 @ID = 143 --> 143, 120 @ID = 21 --> 21 

Le problème avec cette requête est qu'il peut y avoir plus de 7-8 niveaux, et je me demandais si je peux le faire dynamicment, de sorte que je ne vais pas m'inquiéter si mon code doit être changé chaque fois qu'il y a une autre ligne avec un relation est ajoutée. Dites si une nouvelle ligne est ajoutée pour replace celle avec l'ID 106, je vais devoir continuer à append.

Merci d'avance pour toute aide

Vous pouvez utiliser un CTE récursif pour get les correspondances:

 with cte as ( select id, acronym, null as newid, id as baseid, 1 as lev, cast(id as varchar(max)) as ids from #GrwHist h where newid is null union all select h.id, h.acronym, h.newid, cte.baseid, cte.lev + 1 cte.ids + ',' + cast(h.id as varchar(max)) as ids from cte join #GrwHist h on h.new_id = cte.id ) select baseid, ids from (select cte.*, max(lev) over (partition by baseid) as maxlev from cte ) cte where maxlev = lev; 

MODIFIER:

S'il y a des duplicates, vous pouvez get chaque identifiant en utilisant:

 select baseid, id from cte order by baseid; 

Obtenir des valeurs sur une ligne est un peu plus compliqué.