我有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。
答案 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;