0

我有表格来测试我需要透视的得分数据,但我被困在如何去做。SQL Server 2008数据透视表没有聚集

我拥有的数据是:

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 2010-03-22 16:47:14

+0

是的,等级的数量是固定的。当分数不可用时,数据集将填充零记录,因此查询总是有13条记录。 – 2010-03-22 16:48:27

回答

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列,因此每个组合的等级和测试类型都会返回单个分数,因此所有聚合将仅返回该组合的特定分数,并且不会对其执行任何操作。

我只在前四个年级完成了这个练习,但我确信你可以告诉你需要添加什么来让它在所有13个年级都能正常工作。

+0

谢谢。这工作。我只是简单地将“从@PivotData”改为我的表名,并在它后面添加了一个WHERE子句,并且一切顺利。在其余的成绩中加入没有问题。 – 2010-03-22 19:55:49

+0

@布赖恩刘易斯,很高兴我一切都解决了。 – 2010-03-22 20:06:30

0

这是一个解决方案。下面的代码使用Oracle的双表为这些区域创建一个虚拟表(例如,听,说等)。然而,对于SQLServer,我相信你可以在每个联合中截断'from dual'子句。该查询执行笛卡尔积,以便将列为导向的成绩下拉到标准化结构(列技能,等级和分数)。然后以正常方式使用这些数据来转发数据。我还添加了“排名”列,以便根据您指定的结果对数据进行排序。

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;