2013-12-17 47 views
1

我有一個表上簡單的選擇給出了讓像下面SQL服務器 - 轉換列行

enter image description here

我想寫一個查詢語句來輸出像下面

enter image description here

有人可以幫我...

+3

聽起來像你想要的樞紐。 –

+1

搜索數據透視表和sql。 – Mihai

+0

你打算如何顯示數據?像這樣旋轉在報表和應用中比在SQL中更容易實現。 –

回答

8

因爲你基本上是旋轉你當前的列SaleIncomeProfit轉換爲行,然後將month值移動到列中,那麼您將首先取消轉移當前列,然後轉動月份。

根據您的SQL Server版本,有幾種方法可以取消數據傳輸。您可以使用UNPIVOT功能或CROSS APPLY:

select month, type, value 
from yourtable 
cross apply 
(
    select 'Sale', sale union all 
    select 'Income', Income union all 
    select 'Profit', Profit 
) c (type, value) 

SQL Fiddle with Demo。這會將您當前的數據轉換爲:

| MONTH | TYPE | VALUE | 
|-------|--------|-------| 
| Jan | Sale | 100 | 
| Jan | Income | 50 | 
| Jan | Profit | 10 | 
| Feb | Sale | 20 | 
| Feb | Income | 40 | 

然後,您可以使用PIVOT功能將月份轉換爲列標題。

select type, Jan, Feb, Mar, Apr 
from 
(
    select month, type, value 
    from yourtable 
    cross apply 
    (
    select 'Sale', sale union all 
    select 'Income', Income union all 
    select 'Profit', Profit 
) c (type, value) 
) d 
pivot 
(
    sum(value) 
    for month in (Jan, Feb, Mar, Apr) 
) piv; 

請參閱SQL Fiddle with Demo

,如果你有一個未知的數個月,那麼你可以使用動態SQL:

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

select @cols = STUFF((SELECT distinct N',' + QUOTENAME(Month) 
        from yourtable 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = N'SELECT type, ' + @cols + N' 
      from 
      (
       select month, type, value 
       from yourtable 
       cross apply 
       (
        select ''Sale'', sale union all 
        select ''Income'', Income union all 
        select ''Profit'', Profit 
       ) c (type, value) 
      ) x 
      pivot 
      (
       sum(value) 
       for month in (' + @cols + N') 
      ) p ' 

execute sp_executesql @query; 

SQL Fiddle with Demo

+0

解決方案看起來不錯。謝謝bluefeet。但是在編寫查詢時,它的動態並不知道月份列表。它也可能會延續到十二月。所以今天當我運行到四月時,明天可能要到六月。任何想法如何解決? –

+0

@KrishnarajBarvathaya看到我的編輯,你將不得不使用動態sql。你的月份值實際上是一個字符串 - jan,feb等?或者它被存儲爲日期?如果代碼存儲爲任一代碼,您將不得不對代碼進行一些調整,但上面的內容會讓您開始。 – Taryn

+0

是否有任何其他直接的方式將行轉換爲列,反之亦然?因爲無論「yourtable」是不是一個簡單的表。它是一個有很多條件的複雜查詢。我也沒有奢望去定義單獨的變量和多個語句。我應該能夠在一個語句中將列轉換爲行。 –

0

您可以使用UNPIVOT然後PIVOT
最好是DO QUERY嵌入式SQL 創建帶有STUFF功能的月份DISTINCT COLUMS,然後 替換爲oMonth IN([2013年1月-2013],[2013年2月],[2013年3月],[2013年4月])
此處核心查詢

SELECT 
* 
FROM 
( SELECT  
oMonth, value,col 
from (
select DATENAME(month,oDate) + '-' + CAST(YEAR( oDate) as varchar) as oMonth,  Sales ,Income,Profit 
FROM   SalesSource 
)A 
unpivot 
(
    value for col in (Sales ,Income,Profit) 
) u 

) as sourceTable 
PIVOT 
(
sum(value) 
FOR oMonth IN ([January-2013], [February-2013], [March-2013], [April-2013]) 
) AS PivotTable;