2013-03-27 43 views
0

如何在SQL中实现精确的转置?SQL Server精确表移调

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 
-------------------------- 
+2

请在网站上搜索PIVOT/UNPIVOT示例。这个问题每天至少要问5次。 – 2013-03-27 15:19:47

回答

1

为了得到结果,你必须首先unpivot的HighLowAvg将这些列转换成行。然后,您将应用数据透视表函数将month值转换为列。 (请参阅:MSDN文档PIVOT/UNPIVOT

由于您使用的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得到的结果。

+1

谢谢真的有帮助。 “Cross Apply”正是我一直在寻找的感谢! – Viggi 2013-03-28 14:42:29

+0

需要改变2008 R2 交叉应用 ( SELECT '高',T。[高] UNION 选择 '低',T语法有点为SQL Server。[小] 工会 SELECT '平均值', t。[Average] )c(col,value))d – Viggi 2013-03-28 15:22:28

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