SQL Server:透视多个聚合

时间:2016-02-27 08:23:04

标签: sql-server database dynamic pivot multiple-columns

我一直在寻找关于我的问题几个小时的答案。

我目前的表格:

StudentName Course  Correct Wrong   Blank   Score
-------------------------------------------------
Student1    Math    38      2       0       95
Student1    English 45      5       0       90
...
Student2    Math    38      2       0       95
Student2    English 45      5       0       90

我想要的是:

             Math                               English
StudentName  Correct    Wrong   Blank   Score   Correct   Wrong Blank   Score
Student1        38      2       0       95      45        5     0       90
Student2        38      2       0       95      45        5     0       90`

...

SELECT     dbo.tbl_Students.StudentName, 
           dbo.tbl_CourseCategories.CourseCategory, 
           dbo.tbl_GeneralTestsScores.Correct, 
           dbo.tbl_GeneralTestsScores.Wrong, 
           dbo.tbl_GeneralTestsScores.NotAnswered, 
           dbo.tbl_GeneralTestsScores.Score
FROM       
           dbo.tbl_AcademicTermsStudents 
INNER JOIN
           dbo.tbl_Students ON dbo.tbl_AcademicTermsStudents.StudentID = dbo.tbl_Students.StudentID 
INNER JOIN
           dbo.tbl_GeneralTestsScores 
INNER JOIN
           dbo.tbl_CourseCategories 

ON         dbo.tbl_GeneralTestsScores.CourseCategoryID = dbo.tbl_CourseCategories.CourseCategoryID 

ON         dbo.tbl_AcademicTermsStudents.StudentID = dbo.tbl_GeneralTestsScores.StudentID
Order By StudentName

我搜索了许多页面,但最终找不到解决方案。

感谢。

编辑:我也接受以下解决方案......

StudentName  Math_C Math_W  Math_B  Math_S   English_C    English_W English_B   English_S
Student1        38      2       0       95      45          5       0       90
Student2        38      2       0       95      45          5       0       90`

1 个答案:

答案 0 :(得分:0)

你可以通过双重支点来实现这一目标。通过在旋转之前为每个主题/分数组合添加新的唯一列。

这是一个静态示例,您可以轻松将其转换为动态数据透视表,以满足更多课程需求。您还可以将原始查询放在CTE中,根据需要插入临时表或内联 - 为了清楚起见,我使用了一个临时表。

希望这有帮助。

--Test Data 
SELECT * INTO #Students FROM (VALUES
('Student1','Math',    38,      2,       0,       95),
('Student1','English', 45,      5,       0,       90),
('Student2','Math',    38,      2,       0,       95),
('Student2','English', 45,      5,       0,       90)
) A (StudentName, CourseName, Correct, Blank, Wrong, Score)

--Pivoting
SELECT StudentName
      ,SUM(Math_Correct) Math_Correct
      ,SUM(Math_Blank) Math_Blank
      ,SUM(Math_Wrong) Math_Wrong
      ,SUM(Math_Score) Math_Score
      ,SUM(English_Correct) English_Correct
      ,SUM(English_Blank) English_Blank
      ,SUM(English_Wrong) English_Wrong
      ,SUM(English_Score) English_Score
 FROM 
    (SELECT 
        S.StudentName
        ,S.CourseName+'_Correct' CourseNameCorrrect
        ,S.CourseName+'_Blank' CourseNameBlank
        ,S.CourseName+'_Wrong' CourseNameWrong
        ,S.CourseName+'_Score' CourseNameScore
        ,S.Correct
        ,S.Blank
        ,S.Wrong
        ,S.Score    
     FROM #Students S ) S2
    PIVOT( MAX(Correct) FOR CourseNameCorrrect IN ([Math_Correct], [English_Correct])) P1
    PIVOT( MAX(Blank) FOR CourseNameBlank IN ([Math_Blank], [English_Blank])) P2
    PIVOT( MAX(Wrong) FOR CourseNameWrong IN ([Math_Wrong], [English_Wrong])) P3
    PIVOT( MAX(Score) FOR CourseNameScore IN ([Math_Score], [English_Score])) P4
    GROUP BY StudentName

StudentName Math_Correct Math_Blank  Math_Wrong  Math_Score  English_Correct English_Blank English_Wrong English_Score
----------- ------------ ----------- ----------- ----------- --------------- ------------- ------------- -------------
Student1    38           2           0           95          45              5             0             90
Student2    38           2           0           95          45              5             0             90