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