在sql server中将两列转换为5行

时间:2016-10-12 09:17:32

标签: sql-server

我有临时数据表。

select * 
from #test

程序输出:

reg  | Years
---------------
6279 | 2016
6641 | 2016
8347 | 2016
6228 | 2015
8596 | 2015
7596 | 2015
6352 | 2015
1245 | 2014
5248 | 2014
6359 | 2014
6785 | 2014
9578 | 2013
4398 | 2013
2986 | 2013
7296 | 2013

但上面的表我需要显示5行。这意味着将列转换为下面的行

years | reg1 | reg2 | reg3 | reg4
------+------+------+------+-----
 2016 | 6279 | 6641 | 8347 | NULL
 2015 | 6228 | 8596 | 7596 | 6352
 2014 | 1245 | 5248 | 6359 | 6785
 2013 | 9578 | 4398 | 2986 | 7296

根据一些建议,我尝试过使用数据透视和裸机,但我仍然没有得到。请帮帮我。

3 个答案:

答案 0 :(得分:4)

以下是使用CROSS TAB技巧

动态实现的方法
DECLARE @sql      VARCHAR(max)='',
        @intr     INT = 1,
        @cnt      INT

SELECT @cnt = (SELECT ( Max([Years]) - Min([Years]) ) + 1
                     FROM   Yourtable)

SET @sql = 'select [Years], '

WHILE @intr <= @cnt
  BEGIN
      SET @sql += 'max(case when rn = '+ Cast(@intr AS VARCHAR(4)) + ' then [reg] end) as [reg'
                  + Cast(@intr AS VARCHAR (100)) + '],'
      SET @intr+=1
  END

SET @sql = LEFT(@sql, Len(@sql) - 1)

SELECT @sql += 'from (select row_number()over(partition by [Years] order by [reg]) as rn,* from Yourtable) a group by [Years]'

--SELECT @sql

EXEC( @sql) 

答案 1 :(得分:2)

对于每年有限数量的记录,您可以在静态SQL查询中使用条件聚合

;WITH temp_with_rn AS (
  SELECT eg, years, ROW_NUMBER() OVER (PARTITION BY Years ORDER BY eg) AS rn
  FROM temp
) 
SELECT years, 
       MAX(CASE WHEN rn = 1 THEN eg END) AS reg1,
       MAX(CASE WHEN rn = 2 THEN eg END) AS reg2,
       MAX(CASE WHEN rn = 3 THEN eg END) AS reg3,
       MAX(CASE WHEN rn = 4 THEN eg END) AS reg4
FROM temp_with_rn
GROUP BY years

答案 2 :(得分:1)

使用PIVOT:

Select * from
(Select *, 'reg' + cast(row_number() over(partition by year order by reg) as varchar(5)) RowVal
from table) x
PIVOT
(
MAX(reg) FOR RowVal in ([reg1], [reg2], [reg3], [reg4])
) y
order by year desc