Reputation: 63
In SQL Server 2008, I have a table tblStock
with 4 columns:
PartCode (NVARCHAR (50))
Role (NVarchar(10))
StockQty (INT)
Location (NVARCHAR(50))
Some example data below:
I have written this code to get the following output:
IF OBJECT_ID('tempdb..#tblData') IS NOT NULL
DROP TABLE #tblData
SELECT *
INTO #tblData
FROM
(SELECT 'A' PartCode, 'Manager' As [Role], 10 StockQty, 'in-A' Location
UNION ALL
SELECT 'B', 'Director' As [Role], 22, 'in-A'
UNION ALL
SELECT 'A', 'Director' As [Role], 1, 'in-B'
UNION ALL
SELECT 'C', 'Director' As [Role], 20, 'in-A'
UNION ALL
SELECT 'D', 'Director' As [Role], 39, 'in-F'
UNION ALL
SELECT 'E', 'Director' As [Role], 3, 'in-D'
UNION ALL
SELECT 'F', 'Director' As [Role], 7, 'in-A'
UNION ALL
SELECT 'A', 'Director' As [Role], 9, 'in-C'
UNION ALL
SELECT 'D', 'Director' As [Role], 2, 'in-A'
UNION ALL
SELECT 'F', 'Director' As [Role], 54, 'in-E') TAB
SELECT *
FROM #tblData
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + Location + ']', '[' + Location + ']')
FROM (SELECT DISTINCT Location FROM #tblData) PV
ORDER BY Location
SELECT @cols += ',[Total]'
DECLARE @NulltoZeroCols NVARCHAR (MAX)
SELECT @NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+Location+'],0) AS ['+Location+']'
FROM (SELECT DISTINCT Location FROM #tblData)TAB
ORDER BY Location FOR XML PATH('')),2,8000)
SELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT PartCode, Role, ' + @NulltoZeroCols + ' FROM
(
SELECT
ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode,
Role,
SUM(StockQty)StockQty ,
ISNULL(Location,''Total'')Location
FROM #tblData
GROUP BY Location,PartCode,Role
WITH CUBE
) x
PIVOT
(
MIN(StockQty)
FOR Location IN (' + @cols + ')
) p
ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode'
EXEC SP_EXECUTESQL @query
Result for the above query is:
I want to get the result like this:
Please share your ideas - thanks!
Upvotes: 1
Views: 246
Reputation: 1
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT p.PartCode, (SELECT TOP 1 Role FROM #tblData t3 WHERE t3.PartCode = p.PartCode and t3.Role = t2.Role ) Role, ' + @NullToZeroCols +', ('+ @SumCols+' FROM
(
SELECT
ISNULL(CAST(t1.PartCode AS VARCHAR(30)),''Total'')PartCode,
-- Role,
SUM(StockQty)StockQty ,
ISNULL(Location,''Total'')Location
FROM #tblData t1
GROUP BY Location,t1.PartCode
WITH CUBE
) x
PIVOT
(
MIN(StockQty)
FOR Location IN (' + @cols + ')
) p
left JOIN #tblData t2 on t2.PartCode = p.PartCode
GROUP BY t2.Role,p.PartCode, ' + @cols +'
ORDER BY CASE WHEN (p.PartCode=''Total'') THEN 1 ELSE 0 END,p.PartCode'PRINT @query
EXEC (@query)
Upvotes: 0
Reputation: 63
Updated part will be,
SET @query = 'SELECT PartCode, Role, ' + @NulltoZeroCols + ' FROM
(
SELECT PartCode, Role, StockQty, Location
FROM #tblData
UNION ALL
SELECT PartCode, Role, SUM(StockQty), ''Total'' as Location
FROM #tblData
GROUP BY PartCode, Role
UNION ALL
SELECT
''Total'' PartCode,
''Total'' Role,
SUM(StockQty)StockQty ,
ISNULL(Location,''Total'')Location
FROM #tblData
GROUP BY Location
WITH cube
) x
PIVOT
(
MIN(StockQty)
FOR Location IN (' + @cols + ')
) p
ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode'
Upvotes: 1
Reputation: 249
Not MIN, use SUM. Also, you should not select the Role column.
Try this;
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + Location + ']', '[' + Location + ']')
FROM (SELECT DISTINCT Location FROM #tblData) PV
ORDER BY Location
SELECT @cols += ',[Total]'
DECLARE @NulltoZeroCols NVARCHAR (MAX)
SELECT @NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+Location+'],0) AS ['+Location+']'
FROM (SELECT DISTINCT Location FROM #tblData)TAB
ORDER BY Location FOR XML PATH('')),2,8000)
DECLARE @SumCols NVARCHAR (MAX)
SELECT @SumCols = SUBSTRING((SELECT '+(ISNULL(['+Location+'],0))'
FROM (SELECT DISTINCT Location FROM #tblData)TAB
ORDER BY Location FOR XML PATH('')),2,8000)
PRINT @SumCols
SET @SumCols += ') AS [Total]'
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT PartCode, (SELECT TOP 1 Role FROM #tblData WHERE PartCode=p.PartCode) Role, ' + @NulltoZeroCols +', ('+ @SumCols+' FROM
(
SELECT
ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode,
SUM(StockQty)StockQty ,
ISNULL(Location,''Total'')Location
FROM #tblData
GROUP BY Location,PartCode
WITH CUBE
) x
PIVOT
(
MIN(StockQty)
FOR Location IN (' + @cols + ')
) p
ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode'
PRINT @query
EXEC SP_EXECUTESQL @query
Upvotes: 1