I know this topic is everywhere but I couldn\'t get it to work properly. It\'s probably something very simple.
Here is a sample of the data after a basic query:
Using Dynamic Sql
IF OBJECT_ID('tempdb..#TempData', 'U') IS NOT NULL
DROP TABLE #TempData;
CREATE TABLE #TempData (
[Site] CHAR(3) NOT NULL,
Model VARCHAR(30) NOT NULL,
SomeCount INT NOT NULL DEFAULT(0)
);
INSERT #TempData (Site, Model, SomeCount) VALUES
('AAA', 'ProLiant DL380 G7', 1),
('AAA', 'OptiPlex 790', 500),
('BBB', 'OptiPlex 780', 80),
('CCC', 'OptiPlex 790', 23);
Declare @DynamicCol nvarchar(max),@DynamicColNull nvarchar(max)
,@Sql nvarchar(max)
SELECT @DynamicColNull=STUFF((SELECT DISTINCT ', '+'ISNULL('+QUOTENAME(Model),','+'''0'''+') As '+QUOTENAME(Model)
FROM #TempData FOR XML PATH ('')),1,2,'')
SELECT @DynamicCol=STUFF((SELECT DISTINCT ', '+QUOTENAME(Model) FROM #TempData FOR XML PATH ('')),1,2,'')
SET @Sql='SELECT [Site], '+@DynamicColNull+' From
(
SELECT * from #TempData
)
AS Src
PIVOT
(
MAX(SomeCount) FOR [Model] IN ('+@DynamicCol+')
)AS Pvt'
PRINT @Sql
EXEC(@Sql)
Result
Site OptiPlex 780 OptiPlex 790 ProLiant DL380 G7
AAA 0 500 1
BBB 80 0 0
CCC 0 23 0
Give this a shot...
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
DROP TABLE #TestData;
CREATE TABLE #TestData (
[Site] CHAR(3) NOT NULL,
Model VARCHAR(30) NOT NULL,
SomeCount INT NOT NULL DEFAULT(0)
);
INSERT #TestData (Site, Model, SomeCount) VALUES
('AAA', 'ProLiant DL380 G7', 1),
('AAA', 'OptiPlex 790', 500),
('BBB', 'OptiPlex 780', 80),
('CCC', 'OptiPlex 790', 23);
--==========================================================
DECLARE
@PivotColumns NVARCHAR(4000),
@sql NVARCHAR(4000),
@DeBug BIT = 0;
SELECT
@PivotColumns = CONCAT(@PivotColumns, N',
', QUOTENAME(td.Model), N' = SUM(CASE WHEN td.Model = ', QUOTENAME(td.Model, ''''), N' THEN td.SomeCount END)')
FROM
#TestData td
GROUP BY
td.Model
-- ORDER BY ??? if you want the columns in a specific ordinal position.
;
SET @sql = CONCAT(N'
SELECT
td.[Site]',
@PivotColumns, N'
FROM
#TestData td
GROUP BY
td.[Site];');
IF @DeBug = 1
BEGIN
PRINT (@sql);
END;
ELSE
BEGIN
EXEC sys.sp_executesql @sql;
END;
Results...
Site OptiPlex 780 OptiPlex 790 ProLiant DL380 G7
---- ------------ ------------ -----------------
AAA NULL 500 1
BBB 80 NULL NULL
CCC NULL 23 NULL
From your query
PIVOT
(
max(Model)
FOR Site in ' + @cols + ')
) AS piv
you should use the column Count
in MAX()
function and Model
in FOR...IN
section. this is because your new values will be the Count
and your new columns will be from the values in Model