2013-04-30 58 views
1

我有以下结构和数据表:代表一行SQL服务器在一列多列多行数据

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. 另外请注意,没有必要的算术运算 - 我需要的所有数字都已经存在,它们只需要以列方式表示。

+1

你的要求是什么透视数据。 – 2013-04-30 11:27:03

+0

您可以在SQL Server中使用数据透视功能。你可以找到一个例子[这里] [1] [1]:http://stackoverflow.com/questions/15674373/pivot-rows-to-columns-without-aggregate/15678488#15678488 – 2013-04-30 11:29:43

+0

是,我确实听到了这个问题,但我不知道如何继续...... – 2013-04-30 11:29:52

回答

3

有几种方法,你可以转换将数据行分成列。

在SQL Server,你可以使用旋转功能:

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) 
+0

[查看演示](http://data.stackexchange.com/stackoverflow/query/110890) – hims056 2013-04-30 11:37:49

+0

感谢您的详细解答。我正在处理的实际表格比我的问题更复杂,因此我需要一段时间来尝试解决方案。再次感谢! – 2013-04-30 11:40:49

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;