2009-04-24 6 views
1

table Source:SQL Server PIVOT aide

Create Table ExamAnswers 
{ 
    StudentID varchar(12), 
    QuestionID int, 
    Answer char(1) 
} 

et ce sera rempli de

Bob 1 a 
Bob 2 c 
... 
Bob 100 b 
Chris 1 c 
Chris 2 d 
... 
Chris 100 null 

etc, pour environ 500 étudiants.

Chris n'a pas terminé l'examen, mais la 100ème question est stockée comme nulle, donc il est garanti que chaque étudiant a exactement 100 lignes, mais la réponse réelle est nulle ou de caractère.

Si cela fait une différence, les réponses sont {a, b, c, d, e, f}

Cette configuration fonctionne très bien pour l'application de l'examen réel, et le poinçonnement il est trivial.

Maintenant, j'ai une obligation de déclaration, que, aux fins de vérification, je dois produire une table qui ressemble à ceci:

ID 1 2 ... 100 
Bob a c ... b 
Chris c d ....null 

J'ai donc passé une demi-journée de lecture sur la fonction PIVOT, et je viens de don ne comprends pas.

Cela doit être la documentation la plus impénétrable que j'ai jamais lu. D'une part, il exige et fonction d'agrégat - Que diable suis-je censé agréger ici? Je pense qu'il s'agit de l'utilisation la plus simple possible de la fonction PIVOT, et je ne trouve aucun exemple décent nulle part. AIDEZ-MOI!

Répondre

1

OK résolu. MAX ou MIN fonctionnera sur un champ char. Alors :

Create Table ExamAnswers 
{ 
    StudentID varchar(12), 
    QuestionID int, 
    Answer char(1) 
} 

À l'origine créé

Et puis

SELECT StudentID, [1] as Q1, [2] as Q2, [3] as Q3, [4] as Q4, [5] as Q5 
FROM 
(
SELECT StudentID, QuestionID, Answer 
FROM dbo.ExamAnswers 
) AS piv 
PIVOT 
(
MAX(Answer) 
FOR QuestionID IN ([1], [2], [3], [4], [5]) 
) AS chld 

La confusion réside dans la sélection d'un agrégat où il n'y a aucune raison logique de regrouper quoi que ce soit. Je devrais mentionner que StudentID et QuestionID forment une clef composée, ainsi il n'y a qu'une seule valeur de réponse possible pour n'importe quelle paire SID et QID donnée.

3

Regardez cet article: Using PIVOT and UNPIVOT

Quote:

The following is annotated syntax for PIVOT. 

SELECT <non-pivoted column> , 

    [first pivoted column] AS <column name> , 

    [second pivoted column] AS <column name> , 

    ... 

    [last pivoted column] AS <column name> 

FROM 

    (<SELECT query that produces the data>) 

    AS <alias for the source query> 

PIVOT 

( 

    <aggregation function>(<column being aggregated>) 

FOR 

[<column that contains the values that will become column headers>] 

    IN ([first pivoted column] , [second pivoted column] , 

    ... [last pivoted column]) 

) AS <alias for the pivot table> 

<optional ORDER BY clause> 

Comme vous pouvez le voir, il doit être fonction d'agrégation (colonne étant agrégées). La colonne So Answer de votre tableau doit être un entier (décimal, etc.) et non un caractère (1).

EDIT: MIN() et MAX() fonctionnent pour le type de données char().

Votre table peut ressembler à ceci:

Create Table ExamAnswers 
(
    StudentID varchar(12) NOT NULL, 
    QuestionID int NOT NULL, 
    Answer int 
) 

et instruction SELECT avec PIVOT, qui donnent le résultat que vous avez besoin sera:

SELECT StudentID, [1] as Q1, [2] as Q2, [3] as Q3, [4] as Q4, [5] as Q5 
FROM 
(
SELECT StudentID, QuestionID, Answer 
FROM dbo.ExamAnswers 
) AS piv 
PIVOT 
(
AVG(Answer) 
FOR QuestionID IN ([1], [2], [3], [4], [5]) 
) AS chld 
+0

Réponse EST une lettre. Ce n'est pas un int. Je ne peux pas AVG une lettre. Je ne peux pas SUM un, je ne veux pas un compte. Si la lettre est «a», j'aimerais voir «a». Pourquoi est-ce si difficile? –

+0

clause pivot requise fonction d'agrégation, mais les fonctions d'agrégation (mais COUNT(), dont vous n'avez pas besoin) ne fonctionnent que pour les types de données numériques. –

+0

Ok, vous m'avez fait aller dans la bonne direction, La solution est d'utiliser MAX ou MIN dans ce cas. –