Imagine que você tenha o faturamento mensal de uma empresa:

MêsFaturamento
JulhoR$ 180.000
AgostoR$ 210.000
SetembroR$ 195.000
OutubroR$ 230.000

Olhar para esses números já nos mostra alguma coisa.

Mas normalmente a pergunta seguinte é:

Quanto cada mês cresceu ou caiu em relação ao mês anterior?

Agora precisamos comparar linhas.

Agosto precisa olhar para julho.

Setembro precisa olhar para agosto.

Outubro precisa olhar para setembro.

É justamente esse tipo de problema que ajuda a entender o LAG().

Primeiro precisamos calcular o faturamento mensal

Imagine nossa tabela pedido:

pedido
----------------
ID_PEDIDO
ID_CLIENTE
DATA_PEDIDO
VALOR_TOTAL

Podemos calcular o faturamento por mês:

SELECT
    YEAR(DATA_PEDIDO) AS ANO,
    MONTH(DATA_PEDIDO) AS MES,
    SUM(VALOR_TOTAL) AS FATURAMENTO
FROM pedido
GROUP BY
    YEAR(DATA_PEDIDO),
    MONTH(DATA_PEDIDO);

O resultado poderia ser:

ANOMESFATURAMENTO
20267180000
20268210000
20269195000
202610230000

Até aqui utilizamos uma agregação normal.

Uma linha representa um mês.

Agora surge o problema:

Como colocar o faturamento do mês anterior ao lado do faturamento atual?

É aqui que entra o LAG()

Podemos primeiro calcular o faturamento mensal e depois utilizar LAG():

WITH venda_mensal AS (
    SELECT
        YEAR(DATA_PEDIDO) AS ANO,
        MONTH(DATA_PEDIDO) AS MES,
        SUM(VALOR_TOTAL) AS FATURAMENTO
    FROM pedido
    GROUP BY
        YEAR(DATA_PEDIDO),
        MONTH(DATA_PEDIDO)
)
SELECT
    ANO,
    MES,
    FATURAMENTO,
    LAG(FATURAMENTO) OVER (
        ORDER BY ANO, MES
    ) AS FATURAMENTO_ANTERIOR
FROM venda_mensal;

Agora o resultado fica parecido com:

ANOMESFATURAMENTOFATURAMENTO_ANTERIOR
20267180000NULL
20268210000180000
20269195000210000
202610230000195000

Observe o que LAG() fez.

Para agosto, trouxe julho… para setembro, trouxe agosto… para outubro, trouxe setembro.

Em outras palavras:

LAG permite acessar um valor de uma linha anterior sem perder a linha atual.

Por que precisamos do ORDER BY?

Esta parte é fundamental:

LAG(FATURAMENTO) OVER (
    ORDER BY ANO, MES
)

Para saber qual é a linha anterior, o SQL precisa saber qual é a ordem.

Neste caso:

Julho
↓
Agosto
↓
Setembro
↓
Outubro

Sem uma ordem definida, a expressão “mês anterior” não faria sentido.

💡 Quando utilizar LAG(), uma das primeiras perguntas deve ser:

Anterior em qual ordem?

Agora podemos calcular a diferença

Depois de trazer o faturamento anterior, conseguimos comparar os dois valores.

WITH venda_mensal AS (
    SELECT
        YEAR(DATA_PEDIDO) AS ANO,
        MONTH(DATA_PEDIDO) AS MES,
        SUM(VALOR_TOTAL) AS FATURAMENTO
    FROM pedido
    GROUP BY
        YEAR(DATA_PEDIDO),
        MONTH(DATA_PEDIDO)
),
venda_comparada AS (
    SELECT
        ANO,
        MES,
        FATURAMENTO,
        LAG(FATURAMENTO) OVER (
            ORDER BY ANO, MES
        ) AS FATURAMENTO_ANTERIOR
    FROM venda_mensal
)
SELECT
    ANO,
    MES,
    FATURAMENTO,
    FATURAMENTO_ANTERIOR,
    FATURAMENTO - FATURAMENTO_ANTERIOR AS DIFERENCA
FROM venda_comparada;

Teríamos:

MêsAtualAnteriorDiferença
Julho180.000NULLNULL
Agosto210.000180.000+30.000
Setembro195.000210.000-15.000
Outubro230.000195.000+35.000

Agora nossa consulta não mostra apenas quanto vendemos.

Ela mostra como o resultado mudou.

E por que julho aparece como NULL?

Porque julho é a primeira linha do nosso resultado.

Dentro dos dados analisados, não existe uma linha anterior.

Então:

LAG(FATURAMENTO)

não possui nenhum valor para buscar.

O NULL não é um erro.

Ele está dizendo:

Não existe um período anterior disponível nesta consulta para fazer a comparação.

Cuidado com um detalhe importante

Imagine que nossa base tenha:

Julho
Agosto
Outubro

Setembro não aparece porque não houve registros.

Ao utilizar LAG(), outubro vai olhar para a linha anterior:

Agosto.

Mas agosto não é o mês imediatamente anterior a outubro.

Isso nos mostra algo importante:

LAG() busca a linha anterior de acordo com a ordenação. Ele não entende sozinho o significado de “mês anterior”.

Se sua análise exige todos os meses do calendário, inclusive aqueles sem vendas, você precisa garantir que esses períodos existam no conjunto analisado.

⚠️ Esse detalhe evita muitas interpretações erradas.

O LAG não serve apenas para vendas

Agora que entendemos o raciocínio, podemos trocar o problema.

Podemos comparar:

faturamento deste mês com o anterior;

quantidade vendida hoje com ontem;

preço atual com o preço anterior;

saldo atual com o saldo anterior;

desempenho atual de um produto com o período anterior.

A lógica continua parecida:

valor atual
↓
buscar valor anterior
↓
comparar
↓
medir a mudança

É isso que vale aprender.

Um desafio para você

Já temos:

FATURAMENTO
FATURAMENTO_ANTERIOR

E calculamos:

FATURAMENTO - FATURAMENTO_ANTERIOR

Agora imagine que a empresa pergunte:

Qual foi a variação percentual em relação ao mês anterior?

Por exemplo:

Agosto

Atual:    210.000
Anterior: 180.000

Crescimento: ?

Tente montar o cálculo antes de procurar uma solução pronta.

Você já possui os dois valores necessários.

O restante é raciocínio.

Conclusão

LAG() começa a fazer sentido quando deixamos de olhar cada linha isoladamente.

Nossa pergunta era:

Como o faturamento atual se compara ao período anterior?

Então precisamos:

  1. calcular o resultado de cada período;
  2. definir a ordem desses períodos;
  3. trazer o valor da linha anterior;
  4. comparar os dois valores.

Só depois aparece:

LAG(FATURAMENTO) OVER (
    ORDER BY ANO, MES
)

Não é apenas mais uma Window Function para decorar.

É uma ferramenta para responder uma pergunta muito comum em análise:

O que mudou em relação ao que veio antes?

Próximo passo

Na Coleção A Arte da Query, você pratica SQL a partir de cenários em que existe uma pergunta para investigar antes de existir uma função para utilizar.

Porque no trabalho ninguém vai chegar dizendo:

“Preciso que você use LAG().”

A pergunta será:

“Nossas vendas cresceram ou caíram em relação ao período anterior?”

E seu trabalho será transformar essa pergunta em uma análise.

Aqui fiz questão de incluir um único cuidado técnico realmente importante: LAG() significa linha anterior, não necessariamente mês anterior. Isso mantém o artigo curto, mas evita que o leitor saia com uma compreensão tecnicamente incompleta.

Link: https://artedaquery.com.br/

Tags: | | | |

0 Comentários

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Solicitar exportação de dados

Use este formulário para solicitar uma cópia de seus dados neste site.

Solicitar a remoção de dados

Use este formulário para solicitar a remoção de seus dados neste site.

Solicitar retificação de dados

Use este formulário para solicitar a retificação de seus dados neste site. Aqui você pode corrigir ou atualizar seus dados, por exemplo.

Solicitar cancelamento de inscrição

Use este formulário para solicitar a cancelamento da inscrição do seu e-mail em nossas listas de e-mail.