Pagine

lunedì 20 febbraio 2012

Pivoting Dinamico

Immaginate d'avere una tabella e di volerne effettuare il pivot.
L'istruzione Pivot richiede esplicitamente quali valori debbano essere trasformati in colonne, per esempio :

Select * from MyTable
Pivot(Aggregate_fn(Fields0) for Fields1 in (Values List)) Pvt

Immaginate di non conoscere a priori quali valori debbano essere orizzontalizzati con la pivot perchè il contenuto della tabella è
estremamente variabile. Come fare ?

Grazie al T-SQL dinamico possiamo comporre l'istruzione di Pivot a nostro piacimento.

Vediamo un'esempio.
Creiamo una tabella contenente per ogni mese dell'anno le qta di vendita di ogni prodotto

Use TempDb
Go

Create table TabProdotti
(
 item char(1),
 [year] smallint,
 [month] Tinyint,
 Qta tinyint
)

Insert into TabProdotti values('A',2010,1,65)
   ,('A',2010,2,43)
   ,('C',2010,3,35)
   ,('A',2011,1,88)
   ,('B',2011,2,85)
   ,('C',2011,3,80)

Abbiamo la necessità di creare un report che mostri per ogni Item sulla stessa riga la qta totale di vendita per l'anno in questione.
Con T-SQL dinamico risolviamo il problema...
Ecco come :

Declare @strCmd varchar(Max) = 'Select item,' --Conterrà il comando da eseguire
Declare @ListaCampiOutput as Varchar(max)= '' --Conterrà la lista dei campi in output
Declare @ListaCampiPivot as Varchar(max)= ''  --Conterrà la lista dei valori da "pivotare"

--Creo la lista dei campi in output e da pivotare
;With CTE
As
(
Select distinct [YEAR] from TabProdotti
)
Select @ListaCampiPivot = @ListaCampiPivot + ',[' + Cast([YEAR] as varchar(4))+']' -- Li racchiudo tra []
  ,@ListaCampiOutput = @ListaCampiOutput + ',SUM([' --Faccio la Sum per ogni anno e raggrupperò sull'item
      + Cast([YEAR] as varchar(4)) 
      +']) as [' +Cast([YEAR] as varchar(4)) +']'  -- Do l'alias al campo
from CTE

Select @ListaCampiPivot = SUBSTRING(@ListaCampiPivot,2,len(@ListaCampiPivot))    --Rimuovo il carettere virgola inutile all'inizio della stringa
Select @ListaCampiOutput = SUBSTRING(@ListaCampiOutput,2,len(@ListaCampiOutput)) --Rimuovo il carettere virgola inutile all'inizio della stringa

--Compilo la stringa di pivot
Set @strCmd = @strCmd + @ListaCampiOutput + ' from TabProdotti Pivot(Max(Qta) for [year] in (' 
     +@ListaCampiPivot+')) Pvt group by Item Order By Item'
exec(@strCmd)--Eseguiamo il comando di Pivot

ed ecco il risultato :







Spero vi sia utile !!

Ciao


1 commento:

  1. sarà un commento poco tecnico, ma... che spettacolo!

    grazie
    Germano

    RispondiElimina