0

J'ai une table pour tester les données de score que j'ai besoin de pivoter et je suis bloqué sur la façon de le faire.SQL Server 2008 pivot sans agrégat

J'ai les données ceci:

gradelistening speaking reading writing 
0 0.0 0.0 0.0 0.0 
1 399.4 423.8 0.0 0.0 
2 461.6 508.4 424.2 431.5 
3 501.0 525.9 492.8 491.3 
4 521.9 517.4 488.7 486.7 
5 555.1 581.1 547.2 538.2 
6 562.7 545.5 498.2 530.2 
7 560.5 525.8 545.3 562.0 
8 580.9 548.7 551.4 560.3 
9 602.4 550.2 586.8 564.1 
10 623.4 581.1 589.9 568.5 
11 633.3 578.3 598.1 568.2 
12 626.0 588.8 600.5 564.8 

Mais j'ai besoin comme ceci:

gr0 gr1 gr2 gr3 gr4 gr5 gr6 gr7 ... 
listening 0.0 399.4 461.6 501.0 521.9 555.1 562.7 560.5 580.9... 
speaking 0.0 423.8... 
reading 0.0 0.0 424.2... 
writing 0.0 0.0 431.5... 

Je ne ai pas besoin d'agréger quoi que ce soit, juste faire pivoter les données.

+0

Le nombre de classes est-il fixe (à 12/13 dans cet exemple) ou variable? – Dan

+0

Oui, le nombre de grades est fixe. L'ensemble de données est complété avec des enregistrements mis à zéro lorsque les scores ne sont pas disponibles, il y aura donc toujours 13 enregistrements pour la requête. –

Répondre

2

Ce qui suit est une façon de résoudre le problème, mais je ne suis pas sûr que ce soit le plus efficace.

DECLARE @PivotData table(grade int, listening float, speaking float, reading float, writing float) 
INSERT into @PivotData 
SELECT 0, 0.0, 0.0, 0.0, 0.0 UNION ALL 
SELECT 1, 399.4, 423.8, 0.0, 0.0 UNION ALL 
SELECT 2, 461.6, 508.4, 424.4, 431.5 UNION ALL 
SELECT 3, 501.0, 525.9, 492.8, 491.3 

SELECT TestType, [0] As gr0, [1] as gr1, [2] as gr2, [3] as gr3 
FROM 
(
    SELECT grade, TestType, score 
    FROM 
    (
     SELECT grade, listening, speaking, reading, writing from @PivotData 
    ) PivotData 
    UNPIVOT 
    (
     score for TestType IN (listening, speaking, reading, writing) 
    ) as initialUnPivot 
) as PivotSource 
PIVOT 
(
    max(score) FOR grade IN ([0], [1], [2], [3]) 
) as PivotedData 

En fait ce que je faisais était initialement UNPIVOT les données pour obtenir une table qui contient le grade, TestType et marquer chacun dans sa propre colonne, je pivotée les données pour obtenir la réponse que vous voulez. Le fait que mes données sources Univivot contiennent la colonne TestType fait en sorte que chaque combinaison de grade et de test renvoie un seul score, de sorte que toutes les agrégations renvoient juste ce score particulier pour la combinaison et n'y effectueront rien.

Je l'ai seulement fait pour les 4 premières années, mais je suis sûr que vous pouvez dire ce que vous devez ajouter pour que cela fonctionne pour tous les 13 grades.

+0

Merci. Cela a fonctionné. J'ai simplement changé le "de @PivotData" au nom de ma table et ajouté une clause WHERE juste après cela et tout s'est bien passé. Ajouter dans les grades restants n'était pas un problème. –

+0

@Brian Lewis, super, je suis heureux que tout a fonctionné. –

0

Voici une solution. Le code ci-dessous utilise la table double d'Oracle pour créer une table fictive pour les zones (par exemple, écouter, parler, etc.); cependant, pour SQLServer, je crois que vous pouvez juste tronquer la clause 'from dual' dans chaque union. La requête exécute un produit cartésien afin de ramener les notes axées sur les colonnes dans une structure normalisée (compétence des colonnes, note et score). Ceci est ensuite utilisé de manière normale pour faire pivoter les données. J'ai également ajouté une colonne "rank" afin que les données puissent être triées selon les résultats que vous avez spécifiés.

select skill, rank 
    , max(case grade when 0 then score else null end) gr0 
    , max(case grade when 1 then score else null end) gr1 
    , max(case grade when 2 then score else null end) gr2  
from (
    select skill, rank, grade 
    , case skill when 'listening' then listening 
       when 'speaking' then speaking 
       when 'reading' then reading 
       when 'writing' then writing end score 
    from tmp_grade t, (
    select 'listening' skill, 1 rank from dual 
    union (select 'speaking', 2 from dual) 
    union (select 'reading', 3 from dual) 
    union (select 'writing', 4 from dual) 
) area1 
) 
group by skill, rank 
order by rank;