Comme d'autres l'ont dit, vous pouvez utiliser les opérateurs PIVOT et UNPIVOT. Malheureusement, l'un des problèmes avec PIVOT et UNPIVOT est que vous devez connaître les valeurs sur lesquelles vous allez pivoter à l'avance ou utiliser le SQL dynamique.
Dans votre cas, il semble que vous ayez besoin d'utiliser du SQL dynamique. Pour que cela fonctionne bien, vous devrez faire une liste des produits utilisés dans votre requête. Si vous utilisez la base de données AdventureWorks, votre code ressemblera à ceci:
USE AdventureWorks;
GO
DECLARE @columns NVARCHAR(MAX);
SELECT x.ProductName
INTO #products
FROM (SELECT p.[Name] AS ProductName
FROM Purchasing.Vendor AS v
INNER JOIN Purchasing.PurchaseOrderHeader AS poh ON v.VendorID = poh.VendorID
INNER JOIN Purchasing.PurchaseOrderDetail AS pod ON poh.PurchaseOrderID = pod.PurchaseOrderID
INNER JOIN Production.Product AS p ON pod.ProductID = p.ProductID
GROUP BY p.[Name]) AS x;
SELECT @columns = STUFF(
(SELECT ', ' + QUOTENAME(ProductName, '[') AS [text()]
FROM #products FOR XML PATH ('')
), 1, 1, '');
SELECT @columns;
Maintenant que vous avez vos colonnes, vous pouvez tirer tout ce dont vous avez besoin pivoter avec une requête dynamique:
DECLARE @sql NVARCHAR(MAX);
SET @sql = 'SELECT CustomerName, ' + @columns + '
FROM (
// your query goes here
) AS source
PIVOT (SUM(order_count) FOR product_name IN (' + @columns + ') AS p';
EXEC sp_executesql @sql
Bien sûr, si vous devez vous assurer que vous obtenez des valeurs décentes, vous devrez dupliquer la logique que vous utilisez pour construire @columns et créer une variable @coalesceColumns qui contiendra le code à COALESCE (col_name, 0) si vous avez besoin ce genre de chose dans votre requête.