2016-04-19 53 views
1

我有一個程序,根據傳遞給它的參數在下面生成樞軸(見輸出)。我怎樣才能調用一個pivoted過程作爲一個sql查詢?

我希望能夠插入列之間的年份,因爲我在預期的輸出中顯示,將添加100到這個新列中的pivoted值。

有沒有辦法調用一個數據透視表作爲查詢,以便我可以通過選擇查詢添加這些計算?還是有更簡單的方法?

create table t1 
(
    date int, 
    unita int, 
    unitb int, 
    unitc int 
) 

insert into t1 values (2010, 335, 52, 540) 
insert into t1 values (2011, 384, 70, 556) 
insert into t1 values (2012, 145, 54, 345) 


select * 
from 
(
    select date, value, unit 
    from 
    (
     select * 
     from t1 
    ) x 
    unpivot ([value] for unit in ([unita], [unitb], [unitc])) u 
) a 
pivot 
(
    sum(value) 
    for date in ([2010], [2011], [2012]) 
) p 

OUTPUT:

unit 2010 2011 2012 
---------------------- 
unita 335 384 145 
unitb 52 70 54 
unitc 540 556 345 

預期輸出:

unit 2010 2010a 2011 2011a 2012 
----------------------------------- 
unita 335 435 384 485 145 
unitb 52 150 70 170 54 
unitc 540 640 556 656 345 
+0

什麼決定你需要添加多少列? – DhruvJoshi

回答

1

我不認爲這實際上有一個 '易' 的方法來添加列導致樞軸的。在這種情況下,如果沒有動態sql,你無法離開。所以,這裏的 可能的解決方案之一。我在評論中提出了一些解釋。

DECLARE @dates TABLE ([date] varchar(4)) 
DECLARE @pivotColumns varchar(500) 
DECLARE @query nvarchar(max) 

-- First, you need to construct list of values you need to pivot - `[2010], [2010a], [2011], [2011a], [2012]`. 
SET @pivotColumns = '' 

INSERT INTO @dates 
SELECT DISTINCT [date] FROM t1 

SELECT 
    @pivotColumns = @pivotColumns + '[' + CAST([date] AS varchar(4)) + ']' + 
     CASE 
      WHEN [date] < (SELECT MAX([date]) FROM @dates) THEN + ',[' + CAST([date] AS varchar(4)) + 'a]' 
      ELSE '' 
     END + ',' 
FROM @dates ORDER BY [date] 

SET @pivotColumns = LEFT(@pivotColumns, LEN(@pivotColumns) - 1) 

-- Second - in the innermost query you need all the data for these columns in corresponding rows before unpivot. 
-- So we union main query with itself appending 'a' to 'date' values and 
-- incrementing values in unita, unitb, unitc columns by 100 for each row 
-- except for rows with the maximum 'date' value. 
-- Third - we use our @pivotColumns variable for pivot columns list. That's what 
-- this dynamic query is here for. 

SET @query = 
'select * 
from 
(
    select [date], value, unit 
    from 
    (
     select CAST(date AS varchar(5)) AS [date], unita, unitb, unitc from t1 
     union all 
     select CAST(date AS varchar(5)) + ''a'', unita + 100, unitb + 100, unitc + 100 from t1 
     WHERE [date] < (SELECT MAX([date]) FROM t1) 
    ) x 
    unpivot ([value] for unit in ([unita], [unitb], [unitc])) u 
) a 
pivot 
(
    sum(value) 
    for date in (' + @pivotColumns + ') 
) p 
' 
-- Execute the query. 
exec sp_executesql @query