切换行的列和列的行

时间:2013-04-19 08:26:53

标签: tsql sql-server-2005 pivot unpivot

我有这样的查询:

SELECT 
        Column,
        SUM(Row1) AS Row1,
        SUM(Row2) AS Row2,
        SUM(Row3) AS Row3,
        SUM(Row4) AS Row4,
        SUM(Row5) AS Row5,
        SUM(Row6) AS Row6,
        SUM(Row7) AS Row7,
        SUM(Row8) AS Row8,
        SUM(Row9) AS Row9,
        SUM(Row10) AS Row10,
        SUM(Row11) AS Row11,
        SUM(Row12) AS Row12,
        SUM(Row13) AS Row13,
        SUM(Row14) AS Row14,
        SUM(Row15) AS Row15,
        SUM(Row16) AS Row16,
        SUM(Row17) AS Row17
FROM #temp
GROUP BY
Column

我得到的结果如下:

Column      Row1                                    Row2                                  
----------- --------------------------------------- --------------------------------------- 
1           45.00                                   0.00                                    
2           19.00                                   0.00              

想得到这个:

Row          1                                       2                                  
----------- --------------------------------------- --------------------------------------- 
Row1         45.00                                   19.00                                    
Row2         0.00                                    0.00      

但是列号可能会有所不同,语法必须与sql server 2005兼容。 我怎么能得到这样的东西?

1 个答案:

答案 0 :(得分:1)

根据您当前的查询以及您希望列中的column值,我的建议是同时应用UNPIVOTPIVOT函数。

UNPIVOT函数将采用多个row1row2等列并将它们转换为多行。然后,您可以获取值并将它们转换为列。

查询将是:

select row, [1], [2]
from
(
  select [column], [row], value
  from #temp
  unpivot
  (
    value
    for row in (row1, row2, row3, row4, row5, row6,
                row7, row8, row9, row10, row11, row12,
                row13, row14, row15, row16, row17)
  ) un
) src
pivot
(
  sum(value)
  for [column] in ([1], [2])
) piv;

请参阅SQL Fiddle with Demo

如果你有一个已知数量的值,但是如果值是未知的,那么上面的版本将会很好用,那么你需要对PIVOT和UNPIVOT使用动态SQL:

DECLARE @colsUnpivot AS NVARCHAR(MAX),
   @cols AS NVARCHAR(MAX),
   @query  AS NVARCHAR(MAX)

select @colsUnpivot = stuff((select ','+quotename(C.name)
         from sys.columns as C
         where C.object_id = object_id('yt') and
               C.name != 'column'
         for xml path('')), 1, 1, '')

select @cols = STUFF((SELECT distinct ',' + QUOTENAME([column]) 
                    from yt
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select row, '+@cols+' 
     from
     (
       select [column], [row], value
       from yt
       unpivot
       (
          value
          for [row] in ('+ @colsunpivot +')
       ) u
      ) src
      pivot
      (
        sum(value)
        for [column] in ('+@cols+')
      )piv'

exec(@query);

SQL Fiddle with Demo。两者都给出了结果:

|  ROW |   1 |   2 |
--------------------
| row1 |  55 |  93 |
| row2 | 112 |  21 |
| row3 | 523 |  24 |
| row4 | 665 | 179 |