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
ROLLUP
au lieu deCUBE
.
- Utilisez le code
SELECT @cols += ',[Total]'
etSELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'
. - Utilisez
ROLLUP
au 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