如何将一个透视过程作为sql查询调用?

时间:2016-04-19 03:35:02

标签: sql sql-server tsql

我有一个过程,根据传递给它的参数生成下面的枢轴(参见输出)。

我希望能够在多年之间插入列,因为我在预期输出中显示了将在此新列中为旋转值添加100的列。

有没有办法将pivot proc作为查询调用,以便我可以通过select查询添加这些计算?或者有更简单的方法吗?

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

输出:

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

1 个答案:

答案 0 :(得分: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