2013-03-27 41 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