TABLEAU D'EXEMPLE
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
Obtenez les colonnes pour le pivotement dynamique et remplacez NULL avec 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]'
Vous pouvez utiliser CUBE pour trouver le total des lignes et des colonnes et remplacer NULL avec Total pour les lignes générées depuis 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
- Cliquez ici pour voir le résultat
RÉSULTAT

REMARQUE :Si vous voulez NULL au lieu de zero comme valeurs, utilisez @cols au lieu de @NulltoZeroCols en code pivot dynamique
MODIF :
- N'utilisez pas le code
SELECT @cols += ',[Total]'etSELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'. - Utilisez
ROLLUPau lieu deCUBE.

- Utilisez le code
SELECT @cols += ',[Total]'etSELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'. - Utilisez
ROLLUPau lieu deCUBE. - Modifier
GROUP BY Location,PartCodeàGROUP BY PartCode,Location. - Au lieu de
ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode, utilisezWHERE PartCode<>''TOTAL'' ORDER BY PartCode.

MISE À JOUR :Pour apporter PartName pour OP
Je mets à jour la requête ci-dessous pour ajouter PartName avec résultat. Depuis PartName ajoutera des résultats supplémentaires avec CUBE et pour éviter toute confusion dans AND ou OR conditions, il vaut mieux joindre le résultat pivoté avec le DISTINCT valeurs dans votre table source.
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
- Cliquez ici pour voir le résultat
