在T-SQL中透视数据

时间:2011-08-29 15:59:58

标签: sql sql-server tsql pivot

我有一群人。让我们称他们为A,B,C。我有一张桌子,显示他们每个月的工资是多少......

PERSON|MONTH|PAID
A      JAN   10
A      FEB   20   
B      JAN   10   
B      FEB   20   
B      SEP   30   
C      JAN   10   
C      JUNE  20   
C      JULY  30   
C      SEP   40 

这张表可以并且确实持续多年......

有没有办法透过这个表(没有什么,因为我认为真的需要聚合,通常在枢轴中完成)在一个看起来如下的表中?

     JAN    FEB    MAR    APR    MAY    JUN    JUL    AGU    SEP
A    10     20
B    10     20     -      -      -      -      -      -      30
C    10     -      -      -      -      20     30     -      40

之前没有碰到这样的事情但是假设这是一个常见的问题吗?

2 个答案:

答案 0 :(得分:3)

如果您使用的是SQL Server 2005(或更高版本),请输入以下代码:

DECLARE @cols VARCHAR(1000)
DECLARE @sqlquery VARCHAR(2000)

SELECT  @cols = STUFF(( SELECT distinct  ',' + QuoteName([Month])
                        FROM YourTable FOR XML PATH('') ), 1, 1, '') 


SET @sqlquery = 'SELECT * FROM
      (SELECT Person, Month, Paid
       FROM YourTable ) base
       PIVOT (Sum(Paid) FOR [Person]
       IN (' + @cols + ')) AS finalpivot'

EXECUTE ( @sqlquery )

无论您拥有多少不同的状态,这都会有效。它使用PIVOT动态组装查询。使用动态列进行PIVOT的唯一方法是动态组合查询,这可以在SQL Server中完成。

其他例子:

答案 1 :(得分:2)

我不确定为什么你需要一个动态的#列,因为一年总有12个月。你的月份名称似乎也有点不一致。

示例结果集:

SELECT * FROM (SELECT 'A' [PERSON],'JAN' [MONTH],'10' [PAID]
UNION SELECT 'A','FEB',20
UNION SELECT 'B','JAN',10
UNION SELECT 'B','FEB',20
UNION SELECT 'B','SEP',30
UNION SELECT 'C','JAN',10
UNION SELECT 'C','JUNE',20
UNION SELECT 'C','JULY',30
UNION SELECT 'C','SEP',40) AS A
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p

对你的桌子,这将成为:

SELECT [PERSON],[MONTH],[PAID]
FROM [YOURTABLE]
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p

如果添加年份列,则如下所示:

SELECT * FROM (SELECT 'A' [PERSON],'JAN' [MONTH],'10' [PAID], 2011 [YEAR]
UNION SELECT 'A','FEB',20, 2011
UNION SELECT 'B','JAN',10, 2011
UNION SELECT 'A','FEB',20, 2010
UNION SELECT 'B','JAN',10, 2010
UNION SELECT 'B','FEB',20,2011
UNION SELECT 'B','SEP',30,2011
UNION SELECT 'C','JAN',10,2011
UNION SELECT 'C','JUNE',20,2011
UNION SELECT 'C','JULY',30,2011
UNION SELECT 'C','SEP',40,2011) AS A
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p