【问题标题】:Pivot data in T-SQL在 T-SQL 中透视数据
【发布时间】:2011-11-06 03:37:12
【问题描述】:

我有一群人。让我们称他们为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

以前没有遇到过类似的问题,但假设这是一个常见问题,有什么想法吗?

【问题讨论】:

  • 您仍然可以在MONTH 上“聚合”。只是在您的数据集中它已经聚合了。只需使用 SUM 之类的东西。
  • 您可以对固定数量的列执行此操作,一月..二月...,您不能对可变列数执行此操作
  • ...没有办法对可变列执行此操作?
  • 是的,如果您使用的是 SQL Server 2005 或更高版本,您可以使用动态列数来实现。请参阅下面的答案。

标签: sql sql-server tsql pivot


【解决方案1】:

我不确定为什么需要动态列数,因为一年中总是有 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

【讨论】:

  • 需要动态列,因为我们不想一遍又一遍地写下每年的月份
  • 如果 [YEAR] 是固定列,则没有理由这样做。请参阅我的第三个示例。
【解决方案2】:

如果您使用的是 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 中完成。

其他例子:

【讨论】:

    猜你喜欢
    • 2012-08-25
    • 2014-08-07
    • 2012-12-28
    • 1970-01-01
    • 1970-01-01
    • 2012-04-09
    • 2015-10-29
    • 2017-02-22
    相关资源
    最近更新 更多