J'écris une procédure stockée qui obtient des données pour un écran entier. Comment puis-je réutiliser le résultat d'une sélection pour l'introduire dans une seconde sélection? Ceci pour des raisons de performance
Exemple simplifié: j'ai 4 tables
La procédure stockée obtient un cas pour récupérer datatables
La première sélection obtient les détails du case
, du group
et de son logging responsible
associé:
select Case.Date, Case.Name, Group.Name, Responsible.Name Responsible.ResponsibleID from Case inner join Group on Group.GroupID=Case.GroupID inner join Responsible on Responsible.ResponsibleID=Group.ResponsibleID where CaseID=@CaseID
La seconde sélection doit get toutes les actions auxquelles le responsable est assigné. Nous avons seulement le caseID et donc nous devons rebuild les jointures:
select Action.* from Case inner join Group on Group.GroupID=Case.GroupID inner join Responsible on Responsible.ResponsibleID=Group.ResponsibleID inner join Action on Action.ResponsibleID=Responsible.ResponsibleID where CaseID=@CaseID
S'il serait possible de réutiliser la variable à partir du résultat précédent, il serait possible de créer la requête suivante qui serait probablement meilleure pour les performances:
Select * from Action where ResponsibleID={ResultSet1}.ResponsibleID
Pensez à conserver vos résultats dans une variable de table. Cela vous permettra d'effectuer plusieurs opérations SQL sur ce jeu de résultats à partir de vos tables permanentes.
DECLARE @Case TABLE ( [CaseDate] datetime, [CaseName] varchar(100), [GroupName] varchar(100), [ResponsibleName] varchar(100), [ResponsibleID] int ) --get all your case details INSERT INTO @Case( [CaseDate],[CaseName], [GroupName],[ResponsibleName],[ResponsibleID]) SELECT Case.Date, Case.Name, Group.Name, Responsible.Name Responsible.ResponsibleID FROM Case INNER JOIN Group ON Group.GroupID=Case.GroupID INNER JOIN Responsible ON Responsible.ResponsibleID=Group.ResponsibleID WHERE CaseID=@CaseID --now get the Action details for the previous case; --are we absolutely sure there is only one row? then an INNER JOIN SELECT A.* FROM Action AS [A] INNER JOIN @Case AS C ON A.ResponsibleID=C.ResponsibleID -- or guard against multiple results in @Case SELECT A.* FROM Action AS [A] WHERE A.ResponsibleID = (SELECT TOP 1 ResponsibleID FROM @Case)
Si vous obtenez des données pour différentes parties de l'écran en même time, lancez une seule requête. Oui – vous obtiendrez les mêmes données dans les colonnes principales, mais c'est le compromis contre le fait d'aller deux fois au server de database.
select [Case].Date, [Case].Name CaseName, [Group].Name GroupName, Responsible.Name ResponsibleName, Responsible.ResponsibleID, Action.* from [Case] inner join [Group] on [Group].GroupID=[Case].GroupID inner join Responsible on Responsible.ResponsibleID=[Group].ResponsibleID inner join Action on Action.ResponsibleID=Responsible.ResponsibleID where [Case].CaseID=@CaseID
D'autres choses que j'ai remarquées à propos de votre requête
Action.*
Afin de ne pas entrer en conflit avec les autres colonnes