Retornando dados do registro anterior ou seguinte com SQL

Retornando dados do registro anterior ou seguinte com SQL

Neste artigo vamos ver como podemos utilizar informações do registro anterior e do próximo registro utilizando SQL. Vamos ver exemplos utilizando MySQL e SQL Server

Os dados que vamos utilizar são o número de novos emplacamentos de veículos leves no Brasil durante os anos de 2021 e 2022. Vamos criar uma tabela onde este valor vai ser registrado por mês.

O que você vai aprender neste artigo?

* Como retornar dados da linha de resultados anterior utilizando a função LAG.

* Como retornar dados da linha de resultados seguinte utilizando a função LEAD.

 

Nosso primeiro passo é criar uma tabela para guardar estas informações.

MySQL

 

CREATE TABLE veiculos (

    id int NOT NULL AUTO_INCREMENT,

    ano int,

    mes int,

    quantidade int,

PRIMARY KEY (id)

);

 

SQL Server

 

CREATE TABLE veiculos (

    id int IDENTITY(1,1) PRIMARY KEY,

    ano int,

    mes int,

    quantidade int

);

 

Os dados que serão utilizados neste artigo são os seguintes:

 

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 1, 162804);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 2, 158470);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 3, 177356);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 4, 164090);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 5, 175691);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 6, 169847);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 7, 162241);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 8, 158267);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 9, 142144);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 10, 149899);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 11, 160748);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2021, 12, 193283);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 1, 116455);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 2, 121026);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 3, 134699);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 4, 136136);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 5, 174584);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 6, 165972);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 7, 168857);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 8, 193326);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 9, 180110);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 10, 168276);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 11, 191562);

INSERT INTO veiculos (ano, mes, quantidade) VALUES (2022, 12, 201791);

 

Retornar dados da linha de resultados anterior utilizando LAG.

 

A sintaxe da função LAG é a seguinte:

 

LAG(nome_do_campo, OffSet) OVER (

    PARTITION BY nome_do_campo

    ORDER BY nome_do_campo [ASC|DESC]

);

 

A função LAG possui dois parâmetros, o primeiro recebe o nome do campo que você deseja retornar informações. O segundo parâmetro é opcional, nele você deve retornar qual o registro anterior que você quer. Por padrão o valor é 1, ou seja, o primeiro registro anterior ao atual.

Após a função LAG você deve obrigatoriamente utilizar a função OVER(). Esta função é utilizada quando você quer particionar os resultados. No MySQL seus parãmetros não são obrigatórios, no SQL Server você deve informar pelo menos 1 deles. PARTITION BY define uma segmentação lógia para os resultados e ORDER BY se aplica a esta segmentação de dados.

No nosso primeiro exemplo, vamos retornar o valor da quantidade da linha anterior. Perceba que nesta consulta estamos ordenando os resultados por ano e mes

 

MYSQL

SELECT ano, mes, quantidade, LAG(quantidade, 1) OVER () as emplacamentos_anteriores

FROM veiculos

ORDER BY ano, mes

 

SQL Server

SELECT ano, mes, quantidade, LAG(quantidade, 1) OVER (ORDER BY ano, mes) as emplacamentos_anteriores

FROM veiculos

ORDER BY ano, mes

 

Como LAG retorna os dados da linha anterior, o primeiro valor do campo emplacamentos_anteriores vai estar como nulo.

O nosso objetivo é retornar a diferença entre a linha atual é a anterior, desta forma vamos ajustar a nossa consulta para que ela fique desta forma:

 

MySQL

SELECT ano, mes, quantidade, quantidade - LAG(quantidade, 1) OVER () as resultado

FROM veiculos

ORDER BY ano, mes

 

SQL Server

SELECT ano, mes, quantidade, quantidade - LAG(quantidade, 1) OVER (ORDER BY ano, mes) as resultado

FROM veiculos

ORDER BY ano, mes

 

Com base nos resultados, você vai ver que em fevereiro de 2021 foram emplacados menos 4334 veículos em relação ao mês de janeiro de 2021.

Vamos ver um exemplo de particionamento de dados. Nosso objetivo agora é comparar os emplacamentos por mês agrupados por ano. Desta forma, será necessário particionar os dados por mes e ordenar po mes. A nossa consulta foi alterada para ordenar os dados primeiro por mês e depois por ano.

 

SELECT ano, mes, quantidade, quantidade - LAG(quantidade, 1) OVER (PARTITION BY mes ORDER BY ano, mes) as resultado

FROM veiculos

ORDER BY mes, ano

 

Perceba que nestes resultados a coluna resultado referente ao ano de 2021 deve mostrar valores nulos.

 

Retornar dados da linha de resultados anterior utilizando LEAD.

 

Agora que você viu como retornar os registros da linha anterior vamos fazer a operação contrária. Para isso, vamos utilizar a função LEAD. A função LEAD tem a mesma sintaxe da função LAG, a diferença é que ao invés de retornar a linha anterior ele retorna a linha seguinte. No exemplo a seguir retornaremos os dados da linha seguinte

 

MySQL

SELECT ano, mes, quantidade, LEAD(quantidade, 1) OVER () as emplacamentos_mes_seguinte

FROM veiculos

ORDER BY ano, mes

 

SQL Server

SELECT ano, mes, quantidade, LEAD(quantidade, 1) OVER (ORDER BY ano, mes) as emplacamentos_mes_seguinte

FROM veiculos

ORDER BY ano, mes

 

Perceba que a úlitma linha retornou o valor do campo emplacamentos_mes_seguinte como nulo.

Da mesma forma que fizemos com LAG, o que queremos não é o valor do campo seguinte, mas a diferença em relação a linha atual. Desta forma, faremos a subtração da quantidade atual pela quantidade da linha seguinte

 

MySQL

SELECT ano, mes, quantidade, quantidade - LEAD(quantidade, 1) OVER () as resultado

FROM veiculos

ORDER BY ano, mes

 

SQL Server

SELECT ano, mes, quantidade, quantidade - LEAD(quantidade, 1) OVER (ORDER BY ano, mes) as resultado

FROM veiculos

ORDER BY ano, mes

 

Você vai perceber que no caso de janeiro 2021 foram emplacados 4334 veiculos a mais do que no mês seguinte.

Para encerrar, vamos fazer o particionamento dos resultados, comparando os mesmos meses de anos diferentes.

 

SELECT ano, mes, quantidade, quantidade - LEAD(quantidade, 1) OVER (PARTITION BY mes ORDER BY ano, mes) as resultado

FROM veiculos

ORDER BY mes, ano

 

Como fizemos o particionamento de dados considerando o mês e a nossa consulta foi ordenada por mês e ano, o campo resultado referente aos meses de 2022 deve estar nulo.

 

Outros conteudos que podem ser de seu interesse

Verificando a estrutura da tabela pelo terminal no MYSQL
27/10/2019SQL

Verificando a estrutura da tabela pelo terminal no MYSQL

Veja a estrutura e os indices da tabela pelo terminal

Saiba mais...
Criando totais e subtotais com agrupamento no SQL
28/08/2022SQL

Criando totais e subtotais com agrupamento no SQL

Veja como criar totais e subtotais para seus resultados no SQL

Saiba mais...

Conteúdo sobre banco de dados sem complicação!