Cursores y Pivot en SQL Server

Cursores y Pivot en SQL Server

En este artículo se utiliza un cursor para mostrar las ventas de los productos en un año determinado, siempre se recomienda usar con cuidado los cursores, estos consumen recursos importantes en el servidor, siempre que use un cursor evalúe usar si es posible otras opciones, además de que la instrucción Select del cursor tenga solamente
los campos necesarios y los filtros adecuados.

En este artículo usamos una CTE (Common Table Expression) y usamos Pivot para mostrar las compras por mes y totalizarlas en una última columna durante el año 1997, puede usar procedimientos almacenados para poder dinamizar el resultado del cursor para cualquier año.

Para mas información ver
Cursores en SQL Server
Pivot en SQL Server
CTE en SQL Server
Agrupamientos
Variables tipo tabla

Ejercicio

El ejercicio muestra los productos y la cantidad de unidades vendidas en 1997, mostrando el detalle de cada mes.

use Northwind
go
set dateformat dmy
go
Declare  cursorVentasAnuales  cursor  for
	with TotalVentas As
		(
			SELECT 
				P.ProductName As 'Producto', 
				MONTH(O.OrderDate) As  'Mes',
				SUM(D.Quantity) As 'Unidades'
			from Products As P
				join [Order Details]  As D on P.ProductID = D.ProductID
				join Orders As O on D.OrderID = O.OrderID
				Where O.OrderDate between '01/01/1997' and '31/12/1997'
			GROUP BY P.ProductName, MONTH(O.OrderDate)
		)
		select 
			Producto, ISNULL([1],0) Ene, ISNULL([2],0) Feb, 
				ISNULL([3],0) Mar, ISNULL([4],0) Abr, ISNULL([5],0) May,
				ISNULL([6],0) Jun, ISNULL([7],0) Jul, ISNULL([8],0) Ago,
				ISNULL([9],0) Sep, ISNULL([10],0) Oct, ISNULL([11],0) Nov, 
				ISNULL([12],0) Dic
			from TotalVentas
			Pivot (SUM(Unidades) 
			for Mes in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]))
			As Tabla
Open cursorVentasAnuales
Declare @VentasAnualesProducto table
	(
	Nombre nvarchar(50), Enero Numeric(9,2), Febrero Numeric(9,2),Marzo Numeric(9,2), Abril Numeric(9,2),
	Mayo Numeric(9,2), Junio Numeric(9,2), Julio Numeric(9,2), Agosto Numeric(9,2), Septiembre Numeric(9,2),
	Octubre Numeric(9,2), Noviembre Numeric(9,2), Diciembre Numeric(9,2), Total Numeric(9,2)
	)
Declare @Nombre nvarchar(50), @Enero Numeric(9,2), @Febrero Numeric(9,2),@Marzo Numeric(9,2), @Abril Numeric(9,2),
	@Mayo Numeric(9,2), @Junio Numeric(9,2), @Julio Numeric(9,2), @Agosto Numeric(9,2), @Septiembre Numeric(9,2),
	@Octubre Numeric(9,2), @Noviembre Numeric(9,2), @Diciembre Numeric(9,2), @Total Numeric(9,2)
Fetch cursorVentasAnuales into 
	@Nombre , @Enero , @Febrero ,@Marzo , @Abril ,
	@Mayo , @Junio , @Julio , @Agosto , @Septiembre ,
	@Octubre , @Noviembre , @Diciembre 
	while (@@FETCH_STATUS = 0)
		Begin
			Set @Total = ( @Enero + @Febrero +@Marzo + @Abril +
				@Mayo + @Junio + @Julio + @Agosto + @Septiembre +
				@Octubre + @Noviembre + @Diciembre )
			insert into @VentasAnualesProducto 
				(Nombre , Enero , Febrero ,Marzo , Abril,
				Mayo , Junio , Julio , Agosto , Septiembre ,
				Octubre, Noviembre , Diciembre , Total)
				values 
				(@Nombre , @Enero , @Febrero ,@Marzo , @Abril ,
				@Mayo , @Junio , @Julio , @Agosto , @Septiembre ,
				@Octubre , @Noviembre , @Diciembre, @Total)
			Fetch cursorVentasAnuales into 
				@Nombre , @Enero , @Febrero ,@Marzo , @Abril ,
				@Mayo , @Junio , @Julio , @Agosto , @Septiembre ,
				@Octubre , @Noviembre , @Diciembre 
		End
close cursorVentasAnuales
Deallocate cursorVentasAnuales
select * from @VentasAnualesProducto
go

La imagen muestra el resultado