2016-04-19 2 views
1

Ich habe eine Prozedur, die den Pivot unterhalb generiert (siehe Ausgabe) basierend auf Parameter übergeben.Wie kann ich eine geschachtelte Prozedur als SQL-Abfrage aufgerufen werden?

Ich möchte in der Lage sein, Spalten zwischen den Jahren einzufügen, wie ich in der erwarteten Ausgabe zeige, die 100 zu den geschwenkten Werten in dieser neuen Spalte hinzufügen wird.

Gibt es eine Möglichkeit, einen Pivot-Prozess als Abfrage aufzurufen, sodass ich diese Berechnungen über Select Query hinzufügen kann? Oder gibt es einen leichteren Weg?

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 

ERWARTETES ERGEBNIS:

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

Was bestimmt, wie viele Spalten Sie hinzufügen müssen? – DhruvJoshi

Antwort

1

Ich glaube nicht, dass es tatsächlich ein 'einfacher' Weg Spalten hinzufügen einen Dreh zu führen. Sie können nicht ohne eine dynamische SQL in diesem Fall entkommen. Also, hier ist eine der möglichen Lösungen. Ich habe ein paar Erklärungen in die Kommentare eingefügt.

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 
Verwandte Themen