Comment get trois différents types de score pour chaque text dans une ligne dans SQL Server?

Je suis un nouveau développeur SQL et j'essaie d'écrire une requête qui récupérera les résultats suivants à partir de trois tables de la database:

ID Text Résultat # 1 Résultat # 2 Résultat # 3

Le schéma pour les trois tables sont:

T_TextScore Table: Id, TextId, Label, Score, TypeId T_Text: Id, Text T_Status Table: Id, Type 

La table T_TextScore contient trois types de scroes différents pour chaque text. J'ai été capable de récupérer les partitions pour tous les texts mais je suis toujours incapable de montrer chaque type de partition pour chaque text dans une rangée comme illustré ci-dessus. Alors pourriez-vous s'il vous plaît me dire comment je peux get le résultat souhaité?

Voici la requête que j'ai et je pense qu'elle n'est pas efficace en termes de performance:

 SELECT T_TextScore.TextId, T_Text.Text, T_TextScore.Label, T_TextScore.Score FROM T_TextScore INNER JOIN T_Text ON T_TextScore.TextId = T_Text.Id WHERE (T_TextScore.TypeId = 3) UNION SELECT T_TextScore.TextId, T_Text.Text, T_TextScore.Label, T_TextScore.Score FROM T_TextScore INNER JOIN T_Text ON T_TextScore.TextId = T_Text.Id WHERE (T_TextScore.TypeId = 4) UNION SELECT T_TextScore.TextId, T_Text.Text, T_TextScore.Label, T_TextScore.Score FROM T_TextScore INNER JOIN T_Text ON T_TextScore.TextId = T_Text.Id WHERE (T_TextScore.TypeId = 5); 

MISE À JOUR: Après avoir utilisé la requête suggérée par @Craig Young, j'ai obtenu deux lignes pour chaque text et je ne sais pas pourquoi. Pourriez-vous m'expliquer pourquoi?

entrez la description de l'image ici

Votre requête ne fait pas exactement ce que vous avez demandé. Ce qui suit serait une bien meilleure façon de faire ce que vous faites actuellement:

 SELECT ts.TextId, t.Text, ts.Label, ts.Score FROM T_TextScore ts /* Table alias makes query much more readable */ INNER JOIN T_Text t ON ts.TextId = t.Id WHERE ts.TypeId IN (3, 4, 5) 

Cependant, la première partie de votre question suggère que vous voulez réellement faire pivoter vos données?

Si c'est le cas, vous pouvez utiliser la syntaxe PIVOT . Ou pivotement manuel:

 SELECT ts.TextId, /* Use aggregate function to get only 1 per TextId */ MAX(t.Text) AS Text, MAX((ts.Label) AS Label, /* Simply move ts.Score to the correct column to be summed. */ SUM(CASE WHEN ts.TypeId = 3 THEN ts.Score ELSE 0 END) AS Score3, SUM(CASE WHEN ts.TypeId = 4 THEN ts.Score ELSE 0 END) AS Score4, SUM(CASE WHEN ts.TypeId = 5 THEN ts.Score ELSE 0 END) AS Score5 FROM T_TextScore ts INNER JOIN T_Text t ON ts.TextId = t.Id WHERE ts.TypeId IN (3, 4, 5) GROUP BY ts.TextId 

NOTE: La syntaxe de PIVOT est un peu plus succincte. Mais étrangement, je l'ai vu courir un peu plus lentement que le pivot manuel à l'occasion. Donc, si la performance est importante, vous devrez faire un benchmark.


Basé sur votre commentaire:

Après avoir utilisé la requête proposée par @Craig Young, j'ai obtenu deux lignes pour chaque text et je ne sais pas pourquoi.

Vous avez probablement supprimé la clause GROUP BY ou inclus Text et Label dans GROUP BY. Cela m'a fait réaliser que j'avais oublié de traiter ces 2 colonnes qui ne faisaient partie ni de l'agrégat ni du groupe.

J'ai mis à jour ma requête ci-dessus de manière appropriée. Cependant, je dois souligner que le manque de données d'échantillon rend difficile de déterminer exactement ce que vous essayez d'atteindre – en particulier avec la colonne Label qui pourrait être différente par type de partition.

Vous voulez une agrégation conditionnelle. Ma meilleure estimation est simplement:

 SELECT ts.TextId, MAX(CASE WHEN ts.TypeId = 3 THEN ts.Score END) as Score_1, MAX(CASE WHEN ts.TypeId = 4 THEN ts.Score END) as Score_2, MAX(CASE WHEN ts.TypeId = 5 THEN ts.Score END) as Score_3 FROM T_TextScore ts GROUP BY ts.TextId;