Funciones para análisis Lag y Lead


Funciones LAG y LEAD

A partir de SQL Server 2017 se incorporan nuevas funciones que simplifican la forma de como  podemos analizar algunos registros, unas de estas funciones (LAG y LEAD) sirven para consultar registros anteriores o posteriores a el registro donde estamos posicionados en un momento, esto es muy útil en algunas ocasiones cuando queremos tomar un valor que viene de otras filas y relacionarlo en un  calculo.

Para poder demostrarlo hagamos un pequeño ejemplo de la siguiente manera:

1.- En nuestro Management Studio creemos una tabla con la siguiente estructura:


CREATE TABLE [dbo].[HistoricoPrecios](
[Cod_producto] [varchar](20) NOT NULL,
[PrecioActual] [decimal](18, 4) NOT NULL,
[PrecioAnterior] [decimal](18, 4) NOT NULL,
[PrecioSiguiente] [decimal](18, 4) NOT NULL
) ON [PRIMARY]
GO

Una vez creada la tabla procedemos a insertar regustros en ella de la siguiente manera:

insert into HistoricoPrecios(Cod_producto,PrecioActual,PrecioAnterior,PrecioSiguiente)
  values('010001',20.00,0,0)

insert into HistoricoPrecios(Cod_producto,PrecioActual,PrecioAnterior,PrecioSiguiente)
  values('010001',22.25,0,0)

insert into HistoricoPrecios(Cod_producto,PrecioActual,PrecioAnterior,PrecioSiguiente)
  values('010001',23.50,0,0)

insert into HistoricoPrecios(Cod_producto,PrecioActual,PrecioAnterior,PrecioSiguiente)
  values('010001',25.75,0,0)

insert into HistoricoPrecios(Cod_producto,PrecioActual,PrecioAnterior,PrecioSiguiente)

  values('010001',27.30,0,0)

Habiendo creado esto, podemos consultar nuestra tabla y ver que los campos de Precio Anterior y siguiente todos los insertamos en cero, la idea es que actualicemos nuestros campos con los respectivos valores que le corresponden, pero primero hagamos una consulta usando Lag y Lead para asegurarnos que tenemos la información como se necesita:

select Cod_producto, PrecioActual,
   LAG(PrecioActual) over(order by PrecioActual) PrecioAnterior,
   LEAD(PrecioActual) over(order by PrecioActual) PrecioSiguiente

from HistoricoPrecios

El resultado de la consulta sera el siguiente:


Si deseamos podemos mejorar nuestra consulta añadiendo unos condicionales para los campos donde tenemos valores Null, cuya causa es por que son los primeros y últimos registros, para ello lo haremos empleando un condicional "Case When", de la siguiente manera:

select Cod_producto, PrecioActual,
   case when LAG(PrecioActual) over(order by PrecioActual)  is null
then 0
else LAG(PrecioActual) over(order by PrecioActual)  end PrecioAnterior,
   case when LEAD(PrecioActual) over(order by PrecioActual) is null
then 0
else LEAD(PrecioActual) over(order by PrecioActual) end PrecioSiguiente

from HistoricoPrecios

Lo que hicimos fue condicionar los campos PrecioAnterior y PrecioSiguiente para que detecte que si estos son Null entonces me cambie por cero y si no me coloque el valor que trae el Lag y el Lead, tambien podemos apreciar que las funciones Lag y Lead deben ir acompañadas de algo que les indique bajo que condición se asignaran los registros anterior o siguiente y es lo que hace over, su función es decirles que el registro anterior depende del orden que se le esta indicando. Hecho esto la consulta mejorada nos quedaría de la siguiente forma:


Ahora si puedo confiar en los registros y actualizar la tabla para que se fijen los valores en ella, y lo hago de la siguiente forma:

update HistoricoPrecios set PrecioActual = resultado.PrecioActual, PrecioSiguiente = resultado.PrecioSiguiente
from (
select Cod_producto, PrecioActual,
   case when LAG(PrecioActual) over(order by PrecioActual)  is null
then 0
else LAG(PrecioActual) over(order by PrecioActual)  end PrecioAnterior,
   case when LEAD(PrecioActual) over(order by PrecioActual) is null
then 0
else LEAD(PrecioActual) over(order by PrecioActual) end PrecioSiguiente

           from HistoricoPrecios

) resultado

Notese que para no salirnos de lo que venimos haciendo colocamos nuestra consulta como sub consulta del update y aprovechar la potencia de SQL reciclando nuestro código y aprovechando sus campos. Una vez corrido estas lineas ya podemos verificar nuestra tabla y ver como quedo su contenido:

Para mas información del tema, puedes consultar el sitio oficial de SQL Server: Lag/Lead

Comentarios

Entradas populares de este blog

Conocer la cantidad de un carácter específico en una cadena de texto

Consultas dinámicas