Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Obtenir un tableau croisé dynamique généré dynamiquement dans une table temporaire

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