Couru dans ce numéro aujourd'hui, et posté sur mon blog. Une courte description de la solution consiste à créer une table temporaire avec une colonne, puis à la MODIFIER dynamiquement à l'aide de sp_executesql. Ensuite, vous pouvez y insérer les résultats du PIVOT dynamique. Exemple de travail ci-dessous.
CREATE TABLE #Manufacturers
(
ManufacturerID INT PRIMARY KEY,
Name VARCHAR(128)
)
INSERT INTO #Manufacturers (ManufacturerID, Name)
VALUES (1,'Dell')
INSERT INTO #Manufacturers (ManufacturerID, Name)
VALUES (2,'Lenovo')
INSERT INTO #Manufacturers (ManufacturerID, Name)
VALUES (3,'HP')
CREATE TABLE #Years
(YearID INT, Description VARCHAR(128))
GO
INSERT INTO #Years (YearID, Description) VALUES (1, '2014')
INSERT INTO #Years (YearID, Description) VALUES (2, '2015')
GO
CREATE TABLE #Sales
(ManufacturerID INT, YearID INT,Revenue MONEY)
GO
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(1,2,59000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(2,2,46000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(3,2,111500000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(1,1,55000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(2,1,42000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(3,1,101500000000)
GO
DECLARE @SQL AS NVARCHAR(MAX)
DECLARE @PivotColumnName AS NVARCHAR(MAX)
DECLARE @TempTableColumnName AS NVARCHAR(MAX)
DECLARE @AlterTempTable AS NVARCHAR(MAX)
--get delimited column names for various SQL statements below
SELECT
-- column names for pivot
@PivotColumnName= ISNULL(@PivotColumnName + N',',N'') + QUOTENAME(CONVERT(NVARCHAR(10),YearID)),
-- column names for insert into temp table
@TempTableColumnName = ISNULL(@TempTableColumnName + N',',N'') + QUOTENAME('Y' + CONVERT(NVARCHAR(10),YearID)),
-- column names for alteration of temp table
@AlterTempTable = ISNULL(@AlterTempTable + N',',N'') + QUOTENAME('Y' + CONVERT(NVARCHAR(10),YearID)) + ' MONEY'
FROM (SELECT DISTINCT [YearID] FROM #Sales) AS Sales
CREATE TABLE #Pivot
(
ManufacturerID INT
)
-- Thats it! Because the following step will flesh it out.
SET @SQL = 'ALTER TABLE #Pivot ADD ' + @AlterTempTable
EXEC sp_executesql @SQL
--execute the dynamic PIVOT query into the temp table
SET @SQL = N'
INSERT INTO #Pivot (ManufacturerID, ' + @TempTableColumnName + ')
SELECT ManufacturerID, ' + @PivotColumnName + '
FROM #Sales S
PIVOT(SUM(Revenue)
FOR S.YearID IN (' + @PivotColumnName + ')) AS PivotTable'
EXEC sp_executesql @SQL
SELECT M.Name, P.*
FROM #Manufacturers M
INNER JOIN #Pivot P ON M.ManufacturerID = P.ManufacturerID