2011-08-29 12 views
5

Tengo un grupo de personas. Vamos a llamarlos A, B, C. Tengo una tabla que muestra la cantidad que se paga cada mes ....Datos de pivote en 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 

En esta tabla se puede y de hecho se prolongan durante años y años ..

¿Hay una manera de girar esta tabla (nada, como veo, realmente debe agregarse, lo que generalmente se hace en pivotes) ¿En una tabla que se parece a lo siguiente?

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

No he encontrado algo como esto antes, pero asumo que es un problema común cualquier idea?

+0

Puede seguir " agregado "on' MONTH ". Es solo que en su conjunto de datos ya está agregado. Solo usa algo como 'SUM'. – Yuck

+0

puede hacer esto para un número fijo de columnas, Jan..Feb ..., no puede hacer esto para la variable n. ° de columnas –

+0

... ¿No hay forma de hacer esto para columnas variables? – JBone

Respuesta

3

Si está utilizando SQL Server 2005 (o superior), aquí está el código:

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) 

Esto funcionará sin importar cuántas estatus diferente que tiene. Arregla dinámicamente una consulta con PIVOT. La única forma en que puede hacer PIVOT con columnas dinámicas es ensamblando la consulta dinámicamente, lo que se puede hacer en SQL Server.

Otros ejemplos:

2

no estoy seguro de por qué necesita una dinámica # de columnas, ya que siempre hay 12 meses en un año. También los nombres de tus meses parecen un poco inconsistentes en longitud.

Muestra conjunto de resultados:

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 

contra su mesa este se convertiría en:

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 

Si se agrega una columna de año se ve así:

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

Necesita una columna dinámica porque no queremos escribir los meses para cada año una y otra vez – JBone

+0

No hay ninguna razón para hacerlo si [AÑO] es una columna fija. Mira mi tercer ejemplo. – Kenneth