Comment joindre les résultats de deux requêtes dans SQL Server?

Ceci est ma deuxième question SQL aujourd'hui – je suis un peu novice sur les choses de DBA …

J'essaye de joindre une requête complexe de sql pour merge datatables dans environ 12 tables dans 1 table simple. Bien qu'il y ait des relations de un à plusieurs dans la database, je connais le nombre maximum de chacune d'entre elles.

Donc, j'ai (avec l'aide de stack overflow!) Aplatir le premier niveau de ma database, et avoir une paire de requêtes, qui doivent maintenant être jointes:

(abrégé)

SELECT A.StudentId, C1.Topic AS SIoC1, C1.Level AS SIoCScore1 FROM Assessment A LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1 WHERE A.Type = 'School' SELECT A.StudentId, C1.Topic AS PIoC1, C1.Level AS PIoCScore1 FROM Assessment A LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1 WHERE A.Type = 'Parent' 

Est-il possible de nommer les requêtes comme des alias?
Ou comment puis-je joindre ces deux requêtes de sorte que la sortie est comme:

 | A.Id | SIoC1 | SIoCScore1 | PIoC1 | PIoCScore1 | 

** MISE À JOUR ** Le domaine sous-jacent est qu'une évaluation est effectuée, sur laquelle l'école et le parent doivent signaler. Ainsi, la ligne unique identifie une évaluation qui contient à la fois des valeurs École et Parent.

J'utilise SQL Server 2005.

Merci!

* AUTRE MISE À JOUR * Cette requête semble faire le travail …

 SELECT PreConcerns.StudentId, TIoC1, TIoCScore1, PIoC1, PIoCScore1 FROM Assessment PreConcerns LEFT OUTER JOIN ( SELECT P.StudentId, C1.Topic AS TIoC1, C1.Level AS TIoCScore1 FROM Assessment P LEFT JOIN Concern C1 ON P.Id = C1.Assessment_Id and C1.TopicNumber = 1 WHERE P.Type = 'School' ) scons ON scons.StudentId= PreConcerns.StudentId LEFT OUTER JOIN ( SELECT P.StudentId, C1.Topic AS PIoC1, C1.Level AS PIoCScore1 FROM Assessment P LEFT JOIN Concern C1 ON P.Id = C1.Assessment_Id and C1.TopicNumber = 1 WHERE P.Type = 'Parent' ) pcons ON pcons.StudentId = PreConcerns.StudentId 

MISE À JOUR SUPPLÉMENTAIRE (prendre 2!) ** (Je ne suis pas sûr si je devrais rouvrir cela comme une nouvelle question ??!) Je suis returnné au travail aujourd'hui, pour find ma «solution» ci-dessus n'a pas tout à fait résoudre le problème – il crée deux rangées pour chaque évaluation.

Donc, pour récapituler, j'ai les arrays suivants:

 Student (int:id, varchar(50):name) Assessment (int:id, date:date, int:StudentId, ) Concern (int:id, int:assessment_id, varchar(20):topic, int:level) 

Ainsi, pour chaque étudiant du système, il y a exactement deux évaluations – une avec le type «École» et une avec le type «Parent».

Je veux créer une seule ligne qui combine les évaluations et les préoccupations:

(pseudo-colonnes 🙂

 | Assessment.StudentId | SchoolConcernTopic | SchoolConcernLevel | ParentConcernTopic | ParentConcernLevel | 

ou du sql ci-dessus:

 | PreConcerns.StudentId | SIoC1 | SIoCScore1 | PIoC1 | PIoCScore1 | 

Avec seulement une rangée peuplée par élève, qui combine les deux évaluations. J'ai la structure pour ce travail avec le SQL ci-dessus, mais il returnne deux lignes! Et je ne peux pas find comment mettre à jour ceci pour n'en renvoyer qu'un – toute aide reçue avec gratitude !!

Merci comme toujours!

Cela peut être fait avec une seule requête. La clause IN est juste une façon A.Type = 'School' OR A.Type = 'Parent' de dire A.Type = 'School' OR A.Type = 'Parent'

 SELECT A.Id, C1.Topic AS PIoC1, C1.Level AS PIoCScore1 FROM Assessment A LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1 WHERE A.Type IN ('School','Parent') 

Assurez-vous que les noms de champs que vous voulez sont spécifiés sur la première requête, puis UNION ALL les deux requêtes; si vous voulez un set de résultats marqués à la fin de l'autre.

Ignorez ma première réponse, je prends des ordures car cela n'obtiendra pas le résultat que vous voulez. Pardon.

Si vous voulez que la sortie ait des colonnes répétées, où SIoC1 et PIoC1 sont essentiellement les mêmes mais avec un nom différent selon que la ligne provient d'une 'École' ou 'Parent' alors votre set de résultats se refinda avec NULLS partout, par exemple (données randoms utilisées car vous ne fournissez pas de données d'échantillon)

 | A.Id | SIoC1 | SIoCScore1 | PIoC1 | PIoCScore1 | 1 A 10 NULL NULL -- Row type 'School' 2 NULL NULL B 20 -- Row type 'Parent' etc. etc. 

Si datatables sont stockées dans la même table, avec les mêmes noms de champ, utilisez un autre champ pour distinguer les lignes, telles que Type , et affichez-le dans les résultats.

Une requête peut être suffisante:

 SELECT A.Id, A.Type, C1.Topic AS IoC1, C1.Level AS IoCScore1 FROM Assessment A LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1 WHERE A.Type IN ('School', 'Parent') 

Je pense que cette requête doit renvoyer le même résultat que celui de la section "Mise à jour ultérieure".

Les conditions P.Type = ... ont été déplacées des sections WHERE à ON, ce qui vous permet d'get l'effet désiré sans devoir recourir à des sous-sélections.

 SELECT P.StudentId, CS.Topic AS TIoC1, CS.Level AS TIoCScore1, CP.Topic AS PIoC1, CP.Level AS PIoCScore1 FROM Assessment P LEFT JOIN Concern CS ON P.Id = CS.Assessment_Id and CS.TopicNumber = 1 and P.Type = 'School' LEFT JOIN Concern CP ON P.Id = CP.Assessment_Id and CP.TopicNumber = 1 and P.Type = 'Parent' 

EDIT: Il semble que le regroupement devrait aider là. (Je quitte ma requête initiale, il est donc plus facile de voir les changements nécessaires pour l'exigence mise à jour.)

 SELECT P.StudentId, MAX(CS.Topic) AS TIoC1, MAX(CS.Level) AS TIoCScore1, MAX(CP.Topic) AS PIoC1, MAX(CP.Level) AS PIoCScore1 FROM Assessment P LEFT JOIN Concern CS ON P.Id = CS.Assessment_Id and CS.TopicNumber = 1 and P.Type = 'School' LEFT JOIN Concern CP ON P.Id = CP.Assessment_Id and CP.TopicNumber = 1 and P.Type = 'Parent' GROUP BY P.StudentId 

Vous pouvez tout sélectionner dans une requête et utiliser l'instruction CASE pour remplir uniquement les valeurs le cas échéant

 SELECT A.Id, CASE A.Type WHEN 'School' THEN C1.Topic ELSE NULL END AS SIoC1, CASE A.Type WHEN 'School' THEN C1.Level ELSE NULL END AS SIoCScore1, CASE A.Type WHEN 'Parent' THEN C1.Topic ELSE NULL END AS PIoC1, CASE A.Type WHEN 'Parent' THEN C1.Level ELSE NULL END AS PIoCScore1 FROM Assessment A LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1 WHERE A.Type IN ('School', 'Parent') 

Éditer: De preference, vous stockez la colonne Type afin de pouvoir distinguer les deux types de données que vous vouliez et vous n'avez alors pas besoin de répéter les colonnes comme dans l'exemple ci-dessus. Si vous créez une table, alors pour qu'elle soit conforme à une certaine forme de normalisation, vous ne voudriez pas avoir des colonnes répétées, cependant si vous utilisez cette instruction select dans une VUE, il serait acceptable de le faire.

Les noms des colonnes de résultat doivent être les mêmes (l'alias utilisé) et les mêmes types de données:

 SELECT A.Id, C1.Topic AS Topic, C1.Level AS Level FROM Assessment A LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1 WHERE A.Type = 'School' UNION SELECT A.Id, C1.Topic AS Topic, C1.Level AS Level FROM Assessment A LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1 WHERE A.Type = 'Parent' 
 SELECT A.Id, CASE A.Type WHEN 'School' THEN C1.Topic ELSE NULL END AS SIoC1, CASE A.Type WHEN 'School' THEN C1.Level ELSE NULL END AS SIoCScore1, CASE A.Type WHEN 'Parent' THEN C1.Topic ELSE NULL END AS PIoC1, CASE A.Type WHEN 'Parent' THEN C1.Level ELSE NULL END AS PIoCScore1 FROM Assessment A LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1 WHERE A.Type IN ('School', 'Parent') 

Essayez cette solution

  SELECT * INTO #School FROM ( SELECT A.StudentId, C1.Topic AS SIoC1, C1.Level AS SIoCScore1 FROM Assessment A LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1 WHERE A.Type = 'School' )school SELECT * INTO #Parent FROM ( SELECT A.StudentId, C1.Topic AS PIoC1, C1.Level AS PIoCScore1 FROM Assessment A LEFT JOIN Concern C1 ON A.Id = Assessment_Id and C1.TopicNumber = 1 WHERE A.Type = 'Parent' )parent SELECT SL.StudentId ,SL.SIoC1 ,SL.SIoCScore1 ,PT.PIoC1 ,PT.PIoCScore1 From #School SL LEFT JOIN #Parent PT ON PT.StudentId = SL.StudentId