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
ROLLUP
istället förCUBE
.
2. Visa endast kolumntotal
- Använd koden
SELECT @cols += ',[Total]'
ochSELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'
. - Använd
ROLLUP
istället förCUBE
. - Ändra
GROUP BY Location,PartCode
tillGROUP 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