0

У меня есть таблица для проверки данных оценки, которые мне нужны для поворота, и я зациклен на том, как это сделать.SQL Server 2008 pivot без агрегата

У меня есть данные, как это:

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 

Но мне это нужно так:

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... 

мне не нужно агрегировать ничего, просто поворачивать данные.

+0

Число фиксированных марок (в данном примере 12/13) или переменная? – Dan

+0

Да, количество баллов фиксировано. Набор данных дополняется нулевыми записями, когда баллы недоступны, поэтому для запроса всегда будет 13 записей. –

ответ

2

Ниже приведено единственное решение проблемы, но я не уверен, является ли это наиболее эффективным.

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 

В основном то, что я должен был первоначально UNPIVOT данных, чтобы получить таблицу, содержащую класса, TestType и забить каждый в своем столбце, то я повернута данные, чтобы получить ответ, который вы хотите. Тот факт, что мои исходные данные UnPivoted содержат столбец TestType, делает так, чтобы каждая комбинация класса и testype возвращала один балл, поэтому все агрегаты просто вернут этот конкретный балл для комбинации и ничего не будут выполнять на нем.

Я сделал это только для первых 4 классов, но я уверен, что вы можете сказать, что вам нужно добавить, чтобы он работал для всех 13 классов.

+0

Спасибо. Это сработало. Я просто изменил «from @PivotData» на имя моей таблицы и добавил предложение WHERE сразу после него, и все прошло гладко. Добавление в оставшиеся классы не было проблемой. –

+0

@ Брайан Льюис, отлично, я счастлив, что все сработало. –

0

Решение проблемы. В приведенном ниже коде используется двойная таблица Oracle для создания фиктивной таблицы для областей (например, прослушивания, речи и т. Д.); однако для SQLServer я считаю, что вы можете просто урезать предложение «из двойника» в каждом объединении. Запрос выполняет декартово произведение, чтобы вывести классы, ориентированные на столбцы, в нормализованную структуру (навыки столбцов, класс и оценка). Затем это используется обычным образом для поворота данных. Я также добавил столбец «rank», чтобы данные могли быть отсортированы в соответствии с указанными вами результатами.

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;