EXEMPELTABELL
SELECT * INTO #tblStock
FROM
(
SELECT 'A' PartCode, 10 StockQty, 'WHs-A' Location
UNION ALL
SELECT 'B', 22, 'WHs-A'
UNION ALL
SELECT 'A', 1, 'WHs-B'
UNION ALL
SELECT 'C', 20, 'WHs-A'
UNION ALL
SELECT 'D', 39, 'WHs-F'
UNION ALL
SELECT 'E', 3, 'WHs-D'
UNION ALL
SELECT 'F', 7, 'WHs-A'
UNION ALL
SELECT 'A', 9, 'WHs-C'
UNION ALL
SELECT 'D', 2, 'WHs-A'
UNION ALL
SELECT 'F', 54, 'WHs-E'
)TAB
Hämta kolumnerna för dynamisk pivotering och ersätt NULL med zero
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + Location + ']', '[' + Location + ']')
FROM (SELECT DISTINCT Location FROM #tblStock) PV
ORDER BY Location
-- Since we need Total in last column, we append it at last
SELECT @cols += ',[Total]'
--Varible to replace NULL with zero
DECLARE @NulltoZeroCols NVARCHAR (MAX)
SELECT @NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+Location+'],0) AS ['+Location+']'
FROM (SELECT DISTINCT Location FROM #tblStock)TAB
ORDER BY Location FOR XML PATH('')),2,8000)
SELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'
Du kan använda CUBE för att hitta rad- och kolumnsumman och ersätta NULL med Total för raderna som genereras från CUBE .
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT PartCode,' + @NulltoZeroCols + ' FROM
(
SELECT
ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode,
SUM(StockQty)StockQty ,
ISNULL(Location,''Total'')Location
FROM #tblStock
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'
EXEC SP_EXECUTESQL @query
- Klicka här för att se resultatet
RESULTAT

OBS:Om du vill ha NULL istället för zero som värden, använd @cols istället för @NulltoZeroCols i dynamisk pivotkod
REDIGERA:
1. Visa endast radsumma
- Använd inte koden
SELECT @cols += ',[Total]'ochSELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'. - Använd
ROLLUPistället förCUBE.

2. Visa endast kolumntotal
- Använd koden
SELECT @cols += ',[Total]'ochSELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'. - Använd
ROLLUPistället förCUBE. - Ändra
GROUP BY Location,PartCodetillGROUP BY PartCode,Location. - Istället för
ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode, användWHERE PartCode<>''TOTAL'' ORDER BY PartCode.

UPPDATERING:För att ta med PartName för OP
Jag uppdaterar frågan nedan för att lägga till PartName med resultat. Sedan PartName kommer att lägga till extra resultat med CUBE och för att undvika förvirring i AND eller OR villkor, är det bättre att sammanfoga det pivoterade resultatet med DISTINCT värden i din källtabell.
DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT P.PartCode,T.PartName,' + @NulltoZeroCols + ' FROM
(
SELECT
ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode,
SUM(StockQty)StockQty ,
ISNULL(Location,''Total'')Location
FROM #tblStock
GROUP BY Location,PartCode
WITH CUBE
) x
PIVOT
(
MIN(StockQty)
FOR Location IN (' + @cols + ')
) p
LEFT JOIN
(
SELECT DISTINCT PartCode,PartName
FROM #tblStock
)T
ON P.PartCode=T.PartCode
ORDER BY CASE WHEN (P.PartCode=''Total'') THEN 1 ELSE 0 END,P.PartCode'
EXEC SP_EXECUTESQL @query
- Klicka här för att se resultatet
