SQL将行旋转到列...动态行数

时间:2012-10-12 18:41:52

标签: sql sql-server-2008 tsql pivot

  

可能重复:
  SQL Server dynamic PIVOT query?

我有一个具有以下结构的数据集。

CREATE TABLE #TempTable
  (
     Measure_ID  INT,
     measurement DECIMAL(18, 4)
  )

INSERT INTO #TempTable
VALUES
(1,2.3)
,(1,3.4)
,(1,3.3)
,(2,3)
,(2,2.3)
,(2,4.0)
,(2,4.5)

我需要生成看起来像这样的输出。

1,2.3,3.4,3.3
2,3,2.3,4.0,4.5

基本上它是Measure_ID的一个支点。不幸的是,可以有无限数量的measure_id。所以Pivot出局了。

我希望避免使用CURSORS,但如果这是最好的方法。

1 个答案:

答案 0 :(得分:4)

如果您有一个未知数量的值,那么您可以将PIVOT与动态SQL一起使用:

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

select @cols = STUFF((SELECT distinct ',' 
                        + QUOTENAME('Measurement_' + cast(rn as varchar(10))) 
                    from temptable
                    cross apply
                    (
                      select row_number() over(partition by measure_id order by measurement) rn
                      from temptable
                    ) x
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT measure_id, ' + @cols + ' from 
             (
                select measure_id, measurement,
                  ''Measurement_''
                    + cast(row_number() over(partition by measure_id order by measurement) as varchar(10)) val
                from temptable
            ) x
            pivot 
            (
                max(measurement)
                for val in (' + @cols + ')
            ) p '

execute(@query)

请参阅SQL Fiddle With Demo

如果您有一定数量的值,那么您可以对值进行硬编码,类似于:

SELECT measure_id, [Measurement_1], [Measurement_2], 
               [Measurement_3], [Measurement_4]
from 
(
  select measure_id, measurement,
    'Measurement_'
     + cast(row_number() over(partition by measure_id order by measurement) as varchar(10)) val
  from temptable
) x
pivot 
(
   max(measurement)
   for val in ([Measurement_1], [Measurement_2], 
               [Measurement_3], [Measurement_4])
) p 

请参阅SQL Fiddle With Demo

两个查询都会产生相同的结果:

MEASURE_ID | MEASUREMENT_1 | MEASUREMENT_2 | MEASUREMENT_3 | MEASUREMENT_4
==========================================================================
1          | 2.3           | 3.3           | 3.4           | (null)
2          | 2.3           | 3             | 4             | 4.5