我有一个过程,根据传递给它的参数生成下面的枢轴(参见输出)。
我希望能够在多年之间插入列,因为我在预期输出中显示了将在此新列中为旋转值添加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
答案 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