Din data är redan pivoterad, men måste pivoteras på en annan nivå. Jag tror att det bästa sättet att hantera detta är att avpivotera den först och sedan hantera den korrekta pivotnivån.
Steg 1:Unpivot
Du kan använda SQL 2005 UNPIVOT kommando, eller använd en CROSS JOIN-teknik. Här är exempel på båda. Observera att jag utelämnade månader i mitten för att göra det enkelt. Lägg bara till dem.
-- CROSS JOIN method (also works in SQL 2000)
SELECT
P.Project,
Mo =
DateAdd(mm,
X.MonthNum,
DateAdd(yy, P.[Year] - 1900, '19000101')
),
Amount =
CASE X.MonthNum
WHEN 0 THEN Jan
WHEN 1 THEN Feb
WHEN 11 THEN Dec
END
FROM
ProjectData P
CROSS JOIN (
SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 11
) X (MonthNum)
Varje rad upprepas 12 gånger, sedan drar ett CASE-uttalande ut endast en månad för varje rad, vilket lämnar data fint opivoterad.
-- UNPIVOT method
SELECT
P.Project,
Mo =
DateAdd(mm,
Convert(int, P.MonthNum),
DateAdd(yy, P.[Year] - 1900, '19000101')
),
P.Amount
FROM
(
SELECT Project, [Year], [0] = Jan, [1] = Feb, [11] = Dec
FROM ProjectData
) X UNPIVOT (Amount FOR MonthNum IN ([0], [1], [11])) P
DROP TABLE ProjectData
Ingen av metoderna är en klar prestationsvinnare hela tiden. Ibland fungerar den ena bättre än den andra (beroende på vilken data som pivoteras). UNPIVOT-metoden använder ett filter i exekveringsplanen som CROSS JOIN inte gör.
Steg 2:Pivotera igen
Nu, hur man använder opivoterad data. Du sa inte hur du någon kommer att konsumera detta, men eftersom du måste lägga in data i en utdatafil av något slag, föreslår jag att du använder SSRS (Sql Server Reporting Services), som kommer med SQL Server 2005 utan extra kostnad.
Använd bara matrisen rapportera objekt för att pivotera en av frågorna ovan. Det här objektet bestämmer med glädje vilka datavärden som ska göras till kolumnetiketter när rapporten körs och låter som precis vad du behöver. Om du lägger till en kolumn som formaterar datumet precis som du vill kan du sortera efter Mo-kolumnen, men använd det nya uttrycket som kolumnetikett.
SSRS har också en mängd olika format och schemaläggningsalternativ tillgängliga. Du kan till exempel låta den skicka en Excel-fil via e-post eller spara en webbsida till en filresurs.
Meddela mig om jag har utelämnat något.
För alla som vill se koden ovan i aktion, här är ett skript för dig:
USE tempdb
CREATE TABLE ProjectData (
Project varchar(10),
[Year] int,
Jan decimal(15, 2),
Feb decimal(15, 2),
Dec decimal(15, 2)
)
SET NOCOUNT ON
INSERT ProjectData VALUES ('11-11079', 2008, 0.0, 0.0, 75244.90)
INSERT ProjectData VALUES ('11-11079', 2009, 466.0, 0.0, 0.0)
INSERT ProjectData VALUES ('11-11079', 2010, 855.0, 0.0, 0.0)
INSERT ProjectData VALUES ('01-11052', 2009, 56131.0, 0.0, 0.0)