0

如何在 SQL 中实现精确转置?

Month | High | Low | Avg
-------------------------
Jan   | 10    | 9   | 9.5
-------------------------
Feb   | 8  |  7   | 7.5
-------------------------
Mar   | 7    | 6   | 6.5
-------------------------

结果

------ Jan | Feb | Mar
--------------------------
High-- 10  | 8   | 7
--------------------------
Low--  9   | 7   | 6
--------------------------
Avg    9.5 | 7.5 | 6.5
--------------------------
4

2 回答 2

1

伟大的用途pivotunpivot

with t as (
    select 'Jan' as mon, cast(10.0 as float) as high, cast(9.0 as float) as low, cast(9.5 as float) as average union all
    select 'Feb' as mon, 8.0, 7.0, 7.5
   )
select stat, Jan, Feb, Mar
from (select mon, STAT, value
      from t
      unpivot  (value for stat in (high, low, average)) u
     ) t
pivot (max(value) for mon in (Jan, Feb, Mar)) as pt
于 2013-03-27T15:20:21.163 回答
1

为了获得结果,您首先必须通过将,和列转换为行来取消旋转这些列。然后,您将应用数据透视函数将值转换为列。(参见:MSDN PIVOT/UNPIVOT文档)HighLowAvgmonth

由于您使用的是 SQL Server 2008+,因此您可以使用CROSS APPLYVALUES取消透视。unpivot 的代码是:

select t.month, 
  c.col, 
  c.value
from yourtable t
cross apply
(
  values ('High', high), ('Low', Low), ('Avg', Avg)
) c (col, value)

请参阅SQL Fiddle with Demo。这以可以按月旋转的格式给出结果:

| MONTH |  COL | VALUE |
------------------------
|   Jan | High |    10 |
|   Jan |  Low |     9 |
|   Jan |  Avg |   9.5 |
|   Feb | High |     8 |
|   Feb |  Low |     7 |

一旦数据在行中,您将应用数据透视函数,因此代码将是:

select col, Jan, Feb, Mar
from
(
  select t.month, 
    c.col, 
    c.value
  from yourtable t
  cross apply
  (
    values ('High', high), ('Low', Low), ('Avg', Avg)
  ) c (col, value)
) d
pivot
(
  sum(value)
  for month in (Jan, Feb, Mar)
) piv

请参阅SQL Fiddle with Demo。这给出了结果:

|  COL | JAN | FEB | MAR |
--------------------------
|  Avg | 9.5 | 7.5 | 6.5 |
| High |  10 |   8 |   7 |
|  Low |   9 |   7 |   6 |

由于您正在旋转月份名称,我怀疑您是否需要动态 SQL 版本,但如果您有未知数量的值,那么您可以使用动态 sql 来获取结果。

于 2013-03-27T15:28:15.730 回答