2016-04-19 28 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