将列同时旋转到行和行中。 (SSMS)

时间:2013-02-01 20:28:26

标签: sql sql-server pivot

我有下表...让我们称之为Table1

 TERM           PERIOD  Average     StandardDeviation   Minimum
+ 1 Period      2012Q3  0.00417     0.00722             0
+ 120 Periods   2012Q3  0.02951     0.0014              0.028615
+ 20 Periods    2012Q3  0.009898    0.0037              0.007612
+ 40 Periods    2012Q3  0.018255    0.00262             0.016565
+ 1 Period      2012Q4  0.005       0.007               0
+ 120 Periods   2012Q4  0.026       0.001               0.03
+ 20 Periods    2012Q4  0.007       0.003               0.0042
+ 40 Periods    2012Q4  0.018       0.002               0.0165

有没有办法对此进行编码,所以我可以有一个看起来像这样的表:

TERM           PATHS              2012Q3    2012Q4
+ 1 Period     Average            0.00417   0.005
+ 1 Period     StandardDeviation  0.00722   0.007
+ 1 Period     Minimum            0         0

......等每个期限(+ 120期,+ 40期等)。

2 个答案:

答案 0 :(得分:3)

要生成此结果,您需要同时使用UNPIVOTPIVOT函数。 UNPIVOT获取列AverageStandardDeviationMinimum并将其转换为多行。获得行后,您可以将PIVOT应用于Period值。您的代码与此类似:

select term, paths,[2012Q3], [2012Q4]
from
(
  select term, period, paths, value
  from
  (
    select term, period, Average, StandardDeviation, Minimum
    from table1
  ) s
  unpivot
  (
    value
    for paths in (Average, StandardDeviation, Minimum)
  ) unpiv
) src
pivot
(
  max(value)
  for period in ([2012Q3], [2012Q4])
) piv

请参阅SQL Fiddle with Demo

这也可以使用UNION ALL来取消数据,并使用CASE表达式聚合函数来进行透视:

select term,
  paths,
  max(case when period = '2012Q3' then value end) [2012Q3],
  max(case when period = '2012Q4' then value end) [2012Q4]
from
(
  select term, period, 'Average' Paths, average value
  from Table1
  union all
  select term, period, 'StandardDeviation' Paths, StandardDeviation
  from Table1
  union all
  select term, period, 'Minimum' Paths, Minimum
  from Table1
) src
group by term,  paths

请参阅SQL Fiddle with Demo

如果您拥有已知数量的period值,则上述版本效果很好。如果不这样做,那么你将需要使用动态sql来生成结果:

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

select @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(PERIOD) 
                    from Table1
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query 
    = 'select term, paths, '+@cols+'
       from
       (
         select term, period, paths, value
         from
         (
           select term, period, Average, StandardDeviation, Minimum
           from table1
         ) s
         unpivot
         (
           value
           for paths in (Average, StandardDeviation, Minimum)
         ) unpiv
       ) p
       pivot
       (
          max(value)
          for period in('+@cols+')
       ) piv'

execute(@query)

请参阅SQL Fiddle with Demo

所有版本都会产生相同的结果。

答案 1 :(得分:0)

我将其视为聚合和连接。 。 。

select term, paths,
       MIN(case when period = '2012Q3'
                then (case when which = 'Average' then t.average
                           when which = 'StandardDeviation' then t.StandardDeviation
                           when which = 'Minimum' then t.Minimum
                      end)
            end) as "2012Q3",
       MIN(case when period = '2012Q4' 
                then (case when which = 'Average' then t.average
                           when which = 'StandardDeviation' then t.StandardDeviation
                           when which = 'Minimum' then t.Minimum
                      end)
            end) as "2012Q4"
from Table1 t cross join
     (select 'Average' as paths union all
      select 'StandardDeviation' union all
      select 'Minimum'
     ) const
group by term, paths