0
votes

Comment boucle via la table à l'aide de la boucle et créez une autre table avec des valeurs nécessaires

J'ai deux tables: maintable code> et myTable code>. Mytable a un contrôle unique et un identifiant. J'ai besoin d'ajouter un tout premier effdate code> à partir de maintable code> à Mytable code> basé sur ID code> et contrôlé code >.

 Entrez la description de l'image ici p>

car je dois regarder Précédent code> colonne, puis voir si ce Précédent est dans la colonne code> code> et ainsi de suite. p>

 Entrez la description de l'image ici p>

La sortie souhaitée devrait ressemblent à ceci: strong> p>

 Entrez la description de l'image ici p>


Le ci-dessous est un exemple avec des données factices pour obtenir le bon Effilez code> en fournissant une valeur code> code>. Ça fonctionne, mais comment puis-je boucler à travers l'ensemble gestable code>, récupérer id code> s et effondre code> dans une table séparée, puis joindre cette table à MyTable CODE>? P>

-- create sample table #MainTable
IF OBJECT_ID('tempdb..#MainTable') IS NOT NULL DROP TABLE #MainTable;
create table #MainTable (ControlNo int, ID varchar(50), PreviousID varchar(50), EffDate date)
insert into #MainTable values
(3333,'QuoteID3','QuoteID2', '2020-08-25'),
(2222,'QuoteID2','QuoteID1', '2019-08-25'),
(1111,'QuoteID1',NULL, '2018-08-25'),
(7777,'QuoteID6','QuoteID5', '2020-02-10'),
(6666,'QuoteID5',NULL, '2019-02-10')
--select * from #MainTable

-- create sample table #MyTable
IF OBJECT_ID('tempdb..#MyTable') IS NOT NULL DROP TABLE #MyTable;
create table #MyTable (ControlNo int, ID varchar(50), EffDate date)
insert into #MyTable values 
(3333,'QuoteID3',NULL),
(7777,'QuoteID6',NULL)
--select * from #MyTable


4 commentaires

"Pourquoi voulez-vous faire boucle en premier lieu?" : Probablement depuis qu'il vient du monde en développement et a vu de l'aide pour comprendre que les bases de données tabulaires fonctionnent mieux avec le jeu de lignes et non à la ligne de ligne :-)


Oh, s'il y a une façon, je peux éviter la boucle qui serait génial.


J'ai pensé à utiliser des jointures mais que le nombre de précédents n'est pas constant


Remarque latérale séparée, vous êtes mieux à partir d'une fonction de valeur de table en ligne sur cette fonction scalaire. Il a aussi un top 1 , mais pas de code par , ce qui signifie que une ligne arbitraire peut être retourné, ce qui pourrait facilement ne pas être identique une fois chaque fois que vous exécutez ladite fonction.


4 Réponses :


1
votes

Vous pouvez utiliser un CTE récursif pour ceci:

WITH cte 
AS
(

SELECT m.ID,m.PreviousID
FROM MainTable m
JOIN MainTable m2
     ON m.previousID = m2.ID
WHERE m2.previousID IS NULL

UNION ALL

SELECT m2.ID,cte.previousID
FROM cte
JOIN MainTable m2
     ON m2.previousID = cte.ID

)

SELECT *
FROM cte;


0 commentaires

2
votes

Utiliser CTE comme ci-dessous, vous pouvez obtenir les résultats souhaités. voir la démonstration en direct

En savoir plus sur les CTES récursives ici xxx


0 commentaires

2
votes

Vous pouvez utiliser une requête récursive pour traverser la hiérarchie.

Je commencerais en rejoignant la table d'origine avec la table principale, qui limite les chemins des lignes que nous sommes intéressés. Ensuite, vous pouvez recourir à la parent. Enfin, nous devons filtrer sur le parent supérieur par chemin suivant: top () code> et row_number () code> est utile pour cela. P>

Considérez: p>

controlno | id       | effdate   
--------: | :------- | :---------
     3333 | QuoteID3 | 2018-08-25
     7777 | QuoteID6 | 2019-02-10


3 commentaires

Ce n'est pas une bonne solution à première vue. Il n'y a aucune raison de faire la jointure qui coûte beaucoup de coût dans chaque itération de la récursive.


@Ronenarriement: pas du tout. Comme je l'ai expliqué dans ma réponse, la jointure ne se produit que dans l'ancre de la requête, ce qui limite le nombre de rangées que nous devons ensuite faire itérair à ceux que nous avons vraiment besoin.


Merci. C'est bien!



1
votes

Voici un exemple de travail de l'approche CTE avec la table fournie xxx

résultats xxx


0 commentaires