我有一个包含以下结构和数据的表:
batsman | runs | year
1 | 800 | 2012
1 | 950 | 2011
1 | 1050 | 2010
2 | 550 | 2012
2 | 650 | 2011
2 | 400 | 2010
3 | 900 | 2012
需要通过SQL查询选择此数据:
batsman | 2012 | 2011 | 2010
1 | 800 | 950 | 1050
2 | 550 | 650 | 400
3 | 900 | - | -
我正在尝试通过存储过程执行此操作。可以假设列数(以年为单位)是固定的:3。 另请注意,不需要算术运算 - 我需要的所有数字都已经存在,它们只需要按列表示。
答案 0 :(得分:3)
有几种方法可以将数据行转换为列。
在SQL Server中,您可以使用PIVOT功能:
select batsman, [2012], [2011], [2010]
from
(
select batsman, runs, year
from yourtable
) d
pivot
(
sum(runs)
for year in ([2012], [2011], [2010])
) piv;
或者您可以使用具有CASE
表达式的聚合函数:
select batsman,
sum(case when year = 2012 then runs else 0 end) [2012],
sum(case when year = 2011 then runs else 0 end) [2011],
sum(case when year = 2010 then runs else 0 end) [2010]
from yourtable
group by batsman;
如果您拥有已知数量的列,则其他版本将非常有用。但是,如果您将拥有未知数量的year
值,那么您将需要使用动态SQL:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(year)
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT batsman,' + @cols + '
from
(
select batsman, runs, year
from yourtable
) x
pivot
(
sum(runs)
for year in (' + @cols + ')
) p '
execute(@query)
答案 1 :(得分:1)
请尝试PIVOT:
declare @tbl as table(batsman int, runs int, yearr int)
insert into @tbl values
(1, 800, 2012),
(1, 950, 2011),
(1, 1050, 2010),
(2, 550, 2012),
(2, 650, 2011),
(2, 400, 2010),
(3, 900, 2012)
select * From @tbl
select *
from
(
select *
from @tbl
) d
pivot
(
max(runs)
for yearr in ([2012], [2011], [2010])
) piv;
答案 2 :(得分:1)
您需要使用数据透视表,如下所示: http://blogs.msdn.com/b/spike/archive/2009/03/03/pivot-tables-in-sql-server-a-simple-sample.aspx
例如:
select * from batsman
pivot (runs for Year in ([2012], [2011], [2010])) as runsperyear