Proporciona un mecanismo fácil de SQL SERVER para transformar fil as en columnas. Para ver el uso de PIVOT crearemos algunas tablas tablas temporales. Crear la siguiente siguie nte tabla temporal: temporal: -- Creando tabla temporal #Ingresos CREATE TABLE TABLE #Ingresos #Ingresos (Curso VARCHAR VARCHAR( (50 50), ), Año Año INT INT, , Ganancias MONEY MONEY) ) GO -- Agregando algunos registros INSERT INTO INTO #Ingresos #Ingresos VALUES ('.NET' '.NET', ,2014 2014, ,10000 10000), ), ('Java' 'Java', ,2014 2014, ,20000 20000), ), ('.NET' '.NET', ,2014 2014, ,5000 5000), ), ('.NET' '.NET', ,2015 2015, ,48000 48000), ), ('Java' 'Java', ,2015 2015, ,30000 30000); ); GO
Ejemplo Ejempl o 1: 1:
En este ejemplo ej emplo los lo s datos de la tabla #Ingresos se hace pivotar de modo que el curso se convie rte en los encabezados de columna.
Tabla Temporal #Ingresos #Ingresos
PIVOT sobre columna Curso
Resultado del PIVOT con e l campo Curso como columnas
SELECT * FROM FROM #Ingresos #Ingresos PIVOT (SUM (SUM( (Ganancias Ganancias) ) FOR Curso FOR Curso IN ([.NET] [.NET], , Java)) Java )) AS AS PVT PVT
Script Pivot sobre la tabla #Ingresos, #Ingresos, donde los disti ntos ntos valores del campo Curso son transformados transformados en columnas. SELECT * FROM FROM #Ingresos #Ingresos PIVOT(SUM PIVOT( SUM( (Ganancias Ganancias) ) FOR Curso FOR Curso IN ([.NET] [.NET], , Java Java)) )) AS AS PVT PVT
Ejemplo Ejempl o 2: 2:
En este ej emplo los datos de tabla #Ingresos #Ingresos se hace pivotar de modo modo que el año se convie rte en los encabezados de columna.
Tabla Temporal #Ingresos
PIVOT sobre columna Año
Resultado del PIVOT con el campo Año como columnas
SELECT * FROM #Ingresos PIVOT (SUM(Ganancias) FOR Año IN ([2014],[2015])) AS
Ejemplo 3:
La transformación de los datos de la tabla de Ve ntas con una publicación trimestral los datos de ventas agregadas con Trimestre (Quarters) como las columnas del conjunto de re sultados. Primero creamos la tabla temporal con 500 registros: -- Crea Tabla Temporal CREATE TABLE #Ventas (IdVenta INT IDENTITY(1,1), FechaVta Date) GO -- Rellenar 500 registros de Ventas con -- Random de 0-500 dias como fecha de venta INSERT INTO #Ventas(FechaVta) VALUES(DATEADD(dd, - CONVERT(INT, (1000+1)*RAND()),GETDATE())); GO 500
Observamos en una consulta por agrupación La Obtención las ventas Trimestrales: SELECT DATEPART(YEAR,FechaVta) [Año], DATEPART(QUARTER,FechaVta) [Trimestre], COUNT(*) [NroVentas] FROM #Ventas GROUP BY DATEPART(YEAR,FechaVta),DATEPART(QUARTER,FechaVta) ORDER BY 1,2
Como puede obse rvar hemos obtenido el número total de ventas realizadas en cada trimestre de cada año. No olvide que si Ud. Genera la tabla de nuevo l os resultados no serán los mismos del e jemplo dado que son datos aleatorios.
Ahora aplicaremos PIVOT para obtener el Resumen en forma Horizontal: SELECT Año, [1] AS Trim1, [2] AS Trim2, [3] AS Trim3, [4] AS Trim4 FROM (
SELECT YEAR(FechaVta) AS Año, DATEPART(QUARTER, FechaVta) AS Trim, COUNT(*) AS NroVentas FROM #Ventas GROUP BY YEAR(FechaVta), DATEPART(QUARTER,FechaVta) ) As SCR PIVOT(SUM(NroVentas) FOR Trim IN ([1],[2],[3],[4])) AS PVT
Ahora si deseamos la cantidad de ventas por meses: SELECT * FROM ( SELECT YEAR(FechaVta) AS Año, DATENAME(Month, FechaVta) AS Mes, COUNT(*) AS NroVentas FROM #Ventas GROUP BY YEAR(FechaVta), DATENAME(Month, FechaVta) ) As SCR PIVOT(SUM(NroVentas) FOR Mes IN (Enero,Febrero,Marzo,Abril,Mayo,Junio,Julio,Agosto, Septiembre,Octubre,Noviembre,Diciembre)) AS PVT
A los anteriores ejemplos se le aplico PIVOT estático. Es decir los nombres de las columnas en el PIVOT se han asignado mediante nombres estáticos. Ahora vamos a ver cómo podríamos crear PIVOT con nombres de columnas generados dinámicamente. Tomando como ejemplo la tabla temporal #Ingresos Si queremos obtener los ingresos por año y por curso aplicamos el siguiente PIVOT: SELECT * FROM #Ingresos PIVOT(SUM(Ganancias) FOR Curso IN ([.NET], Java)) AS PVT
En este ejemplo las columnas [.Net] y [Java] son columnas Estáticas. Si agregamos más registros con las ganancias de otros cursos esta consulta PIVOT no reflejara los nuevos datos a no ser que agreguemos las columnas necesarias. Para evitar el estar agregando las columnas del PIVOT podríamos generar estas columnas dinámicamente.
INSERT INTO #Ingresos VALUES ('SQL Server',2014,15000), ('Phyton',2014,25000), ('SQL Server',2014,25000), ('SQL Server',2015,50000), ('Phyton',2015,40000);
SELECT * FROM #Ingresos PIVOT(SUM(Ganancias) FOR Curso IN ([.NET], Java)) AS PVT
Como tener una consulta con PIVOT Dinámico: DECLARE @PivotDinamico AS NVARCHAR(MAX) DECLARE @Columnas AS NVARCHAR(MAX) -- Obtiene las columnas para la Columna Pivot SELECT @Columnas= ISNULL(@Columnas + ',','') + QUOTENAME(Curso) FROM (SELECT DISTINCT Curso FROM #Ingresos) AS SCR -- Cadena PIVOT Dinamico SET @PivotDinamico = 'SELECT * FROM #Ingresos PIVOT(SUM(Ganancias) FOR Curso IN (' + @Columnas + ')) AS PVT' -- Ejecutamos la cadena del Pivot Dinamico EXEC (@PivotDinamico)
También se puede haber generado las columnas del PIVOT del siguiente modo: SELECT @Columnas= COALESCE(@columnas + ', ', '') + QUOTENAME(Curso) FROM (SELECT DISTINCT Curso FROM #Ingresos) AS SCR
Ref: http://sqlhints.com/2014/03/18/dynamic-pivot-in-sql-server/