如何在SQL中为多个学生总结视频游戏分数?

时间:2014-12-12 16:08:19

标签: sql sql-server sql-server-2008 sql-server-2008-r2

我有3列数据。第1列是学生的名字,第2列是他们玩的游戏的名称。他们可以玩10种可能的游戏,简称为游戏1至游戏10'。第3列包含学生在游戏中获得的分数,可能是正面或负面。学生可以参加10场比赛中的任何一场0次到多次(没有限制)。每次学生玩任何游戏时,都会创建一行数据。

我想总结一下学生在学生订购的10场比赛中获得的所有分数。因此,行标题将是学生姓名,列标题将是游戏的名称(游戏1至游戏10)。

这是我的代码,我正在做的事情:

SELECT [STUDENT],

SUM ( [SCORE]) 
FROM [Students].[dbo].GameScores
WHERE [GAME] = 'GAME 1'  --swap in the game name that you want

GROUP BY [STUDENT]

我为10场比赛中的每场比赛运行上述代码10次,换掉第2场比赛,第3场比赛,依此类推。然后我会手动切割&必要时将结果粘贴到Excel中。随着游戏数量的增加(达到100),我显然不想运行上述代码来手动提取所有100场比赛的得分总和。

如何更改上述查询以便我可以通过所有10个游戏(或任何X个游戏,可能X等于100)进行迭代并显示结果,以便行标题是学生姓名,列标题是游戏名称和单元格具有特定游戏的学生分数的总和(可以是负数或正数)。

我使用的是SQL Server 2008 R2。

3 个答案:

答案 0 :(得分:1)

这个怎么样:

SELECT student, [Game 1], [Game 2], [Game 3]
FROM Students.dbo.GameScores g
PIVOT (SUM(Score) FOR Game IN ([Game 1], [Game 2], [Game 3])) pvt

您可以在示例中添加游戏4到10,以满足您的要求。

答案 1 :(得分:0)

create table #temp (student varchar(24), score int, Gametitle varchar(20))
    insert into #temp (student , score , Gametitle )
    values
    ('Student1', 100, 'Game1')
    ,('Student1', 90, 'Game2')
    ,('Student1', 80, 'Game3')
    ,('Student2', 100, 'Game1')
    ,('Student2', 100, 'Game2')
    ,('Student2', 100, 'Game3')
    ,('Student3', 100, 'Game1')
    ,('Student3', 50, 'Game4')
    ; 

select 
    student 
    ,[Game1], [Game2], [Game3],[Game4]




from 
#temp


pivot (

    sum(score)
        for Gametitle in ([Game1], [Game2], [Game3],[Game4])) as pivottable

        drop table #temp

结果看起来像

student |   Game1|  Game2|  Game3|  Game4|
Student1|   100  |    90 |    80 |   NULL|
Student2|   100  |   100 |    100|   NULL|
Student3|   100  |   NULL|   NULL|   50  |

如果由于某种原因你不想输出所有的游戏标题,试​​试这个

create table #temp (student varchar(24), score int, Gametitle varchar(20), league varchar(20))
insert into #temp (student , score , Gametitle,league )
values
('Student1', 100, 'Game1','silver')
,('Student1', 90, 'Game2','silver')
,('Student1', 80, 'Game3','silver')
,('Student2', 100, 'Game1','silver')
,('Student2', 100, 'Game2','silver')
,('Student2', 100, 'Game3','silver')
,('Student3', 100, 'Game1','silver')
,('Student3', 50, 'Game4','silver')
,('Student1', 50, 'Game1','silver')


; 

declare @columns nvarchar(max)

select @columns = Coalesce(@columns + ',['+ [Gametitle]+']', '[' + [Gametitle] +']') 
                from (select distinct Gametitle from #temp) columns
                order by Gametitle

declare @query nvarchar (max)

set @query ='
select 

     *



from 
#temp


pivot (

    sum(score)
        for Gametitle in (' + @columns + '))pv



        '

        exec sp_executesql @query

        drop table #temp

答案 2 :(得分:0)

您想要的是将垂直表格转换为水平表格。解决方法是明确或隐含地定义 PIVOT

如果您希望查询完全动态(不是为查询添加新游戏,但查询将自行执行),您将需要使用动态SQL来分析数据并准备数据查询包括所有字段,如下所示:

/* parameters' definition and initializing */
declare @sql nvarchar(max), @columns nvarchar(max);
set @columns = '';

/* Get the unique list of played games */
select @columns = columns + quotename(Game) + ','
from
(
    select distinct Game
    from Students.dbo.Games        
) x
order by Game; /* this will place the payed games in the alphabetical order */

set @columns = left(@columns, len(@columns) - 1); /* to remove last coma */

/* Preparing dynamic SQL based on the played games */
set @sql = 'SELECT student, ' + @columns'
FROM Students.dbo.GameScores g
PIVOT (SUM(Score) FOR Game IN (' + @columns + ')) pvt';

/* Executing the dynamic SQL */
exec sp_executesql @sql;