2011-08-29 14 views
5

Ho un gruppo di persone. Li chiamiamo A, B, C. Ho una tabella che mostra quanto sono stati pagati ogni mese ....Dati pivot in T-SQL

PERSON|MONTH|PAID 
A  JAN 10 
A  FEB 20 
B  JAN 10 
B  FEB 20 
B  SEP 30 
C  JAN 10 
C  JUNE 20 
C  JULY 30 
C  SEP 40 

Questa tabella può e non andare avanti per anni e anni ..

Esiste un modo per girare questa tabella (nulla di ciò che vedo ha davvero bisogno di essere aggregato, cosa che di solito si fa nei pivot) In una tabella che assomiglia al seguente?

 JAN FEB MAR APR MAY JUN JUL AGU SEP 
A 10  20 
B 10  20  -  -  -  -  -  -  30 
C 10  -  -  -  -  20  30  -  40 

Non si è mai imbattuto in qualcosa del genere ma si presume che sia un problema comune qualche idea?

+0

È ancora possibile " aggregare "su" MONTH'. È solo che nel tuo set di dati è già stato aggregato. Basta usare qualcosa come 'SUM'. – Yuck

+0

puoi farlo per un numero fisso di colonne, Jan..Feb ..., non puoi farlo per numero variabile di colonne –

+0

... Non c'è modo di farlo per le colonne variabili? – JBone

risposta

3

Se si utilizza SQL Server 2005 (o superiore), ecco il codice:

DECLARE @cols VARCHAR(1000) 
DECLARE @sqlquery VARCHAR(2000) 

SELECT @cols = STUFF((SELECT distinct ',' + QuoteName([Month]) 
         FROM YourTable FOR XML PATH('')), 1, 1, '') 


SET @sqlquery = 'SELECT * FROM 
     (SELECT Person, Month, Paid 
     FROM YourTable) base 
     PIVOT (Sum(Paid) FOR [Person] 
     IN (' + @cols + ')) AS finalpivot' 

EXECUTE (@sqlquery) 

Questo funziona indipendentemente dal numero di status diverso che avete. Assembla dinamicamente una query con PIVOT. L'unico modo per eseguire PIVOT con colonne dinamiche è assemblare la query in modo dinamico, operazione che può essere eseguita in SQL Server.

Altri esempi:

2

io non sono sicuro perché avete bisogno di un # dinamica di colonne, dato che ci sono sempre 12 mesi in un anno. Anche i nomi dei tuoi mesi sembrano un po 'incoerenti.

Esempio set di risultati:

SELECT * FROM (SELECT 'A' [PERSON],'JAN' [MONTH],'10' [PAID] 
UNION SELECT 'A','FEB',20 
UNION SELECT 'B','JAN',10 
UNION SELECT 'B','FEB',20 
UNION SELECT 'B','SEP',30 
UNION SELECT 'C','JAN',10 
UNION SELECT 'C','JUNE',20 
UNION SELECT 'C','JULY',30 
UNION SELECT 'C','SEP',40) AS A 
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p 

Contro la tua tabella di questo sarebbe diventato:

SELECT [PERSON],[MONTH],[PAID] 
FROM [YOURTABLE] 
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p 

Se si aggiunge una colonna anno sembra che questo:

SELECT * FROM (SELECT 'A' [PERSON],'JAN' [MONTH],'10' [PAID], 2011 [YEAR] 
UNION SELECT 'A','FEB',20, 2011 
UNION SELECT 'B','JAN',10, 2011 
UNION SELECT 'A','FEB',20, 2010 
UNION SELECT 'B','JAN',10, 2010 
UNION SELECT 'B','FEB',20,2011 
UNION SELECT 'B','SEP',30,2011 
UNION SELECT 'C','JAN',10,2011 
UNION SELECT 'C','JUNE',20,2011 
UNION SELECT 'C','JULY',30,2011 
UNION SELECT 'C','SEP',40,2011) AS A 
PIVOT (SUM([PAID]) FOR [MONTH] IN ([JAN],[FEB],[MARCH],[APRIL],[MAY],[JUNE],[JULY],[AUG],[SEP],[OCT],[NOV],[DEC])) p 
+0

È necessaria la colonna dinamica perché non vogliamo scrivere i mesi in per ogni anno più e più volte – JBone

+0

Non c'è motivo per cui è necessario se [ANNO] è una colonna fissa. Vedi il mio terzo esempio. – Kenneth