Funções de Janela no SQL: Uma Série Especial para Transformar Sua Análise de Dados
Aprenda tudo sobre as funções de Janela no SQL, que calculam rankings, médias ao longo do tempo e somas parciais sem repetições desnecessárias no código.
Com essas funções, você garante que os dados importantes sejam mantidos e consegue analisar partes específicas da sua tabela de forma eficiente, sem precisar olhar todo o volume de dados de uma vez.
Esta é uma série especial de 10 episódios dedicada a explorar essas funções e mostrar como elas podem otimizar suas consultas.
As funções de janela no SQL fazem cálculos sobre um conjunto de linhas relacionado à linha atual, sem agrupar e sem perder o detalhe dos dados, diferente do GROUP BY. Usadas com OVER() e PARTITION BY, geram rankings (RANK, DENSE_RANK, ROW_NUMBER), médias móveis, somas acumuladas e comparações entre períodos com LAG e LEAD.
Aula 1 – Rankings com RANK() e DENSE_RANK()
Organizar dados em rankings é fundamental para diversas análises, como identificar clientes mais lucrativos, classificar produtos mais vendidos ou medir o desempenho de uma equipe.
No SQL, as funções de janela permitem calcular essas classificações de forma eficiente, sem perder informações valiosas.
Neste primeiro episódio da nossa série sobre funções de janela, vamos explorar RANK() e DENSE_RANK(), entendendo como usá-las para ordenar registros de maneira prática e organizada.
Pronto para levar suas análises a um novo nível e impressionar com consultas mais avançadas? Então, vamos lá!
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
O que você aprende neste vídeo
Resposta rápida: Esta é a Aula 1 de uma série de 10 sobre funções de janela no SQL. A aula usa RANK() e DENSE_RANK() para ranquear clientes pela renda anual, com OVER() e ORDER BY DESC criando a coluna de posição. A diferença entre as duas: RANK() pula a posição seguinte a um empate, DENSE_RANK() segue sequencial.
Neste vídeo (13 min):
- 1:00 - A série tem 10 aulas dedicadas a funções de janela para análise de dados no SQL
- 2:00 - Funções de janela calculam sobre um conjunto de linhas sem agrupar, permitindo por exemplo o percentual de participação de um produto, soma acumulada mês a mês ou comparação ano contra ano
- 3:00 - O roteiro da série: enésimo maior valor, médias móveis, comparação entre períodos, somas acumuladas, percentuais acumulados, categorização, máximo e mínimo, contribuição percentual e análises segmentadas por grupo, uma técnica por aula
- 4:00 - A tabela usada nos exemplos é a clientes, do banco base, o mesmo banco ensinado no minicurso gratuito da descrição
- 5:00 - O objetivo desta aula: ordenar os clientes pela renda anual e identificar empates corretamente, criando uma coluna de posição
- 6:00 - Por que
ORDER BYsozinho não basta: ele ordena os valores, mas não cria uma coluna com a posição de cada registro - 7:00 - Montagem da consulta:
SELECT nome, email, renda_anual, RANK() OVER (ORDER BY renda_anual DESC) AS posicao FROM clientes - 10:50 - Resultado com
RANK(): Damian em primeiro (170.000), Donald em segundo (160.000), Ângela e Alissa empatadas em terceiro (130.000), e o próximo colocado pula direto para quinto - 11:50 - Trocando para
DENSE_RANK()na mesma consulta, depois do empate em terceiro a numeração segue quarto, quinto, sem pular posição - 12:40 - Próxima aula da série: encontrar o enésimo maior valor com
ROW_NUMBER()
Trechos do vídeo:
- Funções de janela calculam sobre um conjunto de linhas relacionado à linha atual sem agrupar, mantendo o detalhe dos dados, o que as diferencia do
GROUP BY - A função
RANK() OVER (ORDER BY renda_anual DESC)cria uma coluna de posição onde registros empatados recebem o mesmo número, e a posição seguinte pula (terceiro e terceiro, depois quinto) - A função
DENSE_RANK()numera de forma contínua mesmo com empates, sem pular nenhuma posição depois deles - Sozinho, o
ORDER BYordena os valores de uma coluna, mas não cria a coluna de posição que um ranking exige, e é por isso que entra a função de janela
Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:
Não vamos te encaminhar nenhum tipo de SPAM! A Hashtag Treinamentos é uma empresa preocupada com a proteção de seus dados e realiza o tratamento de acordo com a Lei Geral de Proteção de Dados (Lei n. 13.709/18). Qualquer dúvida, nos contate.
Função RANK()
A função RANK() atribui uma posição a cada linha dentro de uma partição, considerando a ordem especificada. Serve para criar rankings de registros ordenados, como em competições ou resultados de vendas.
É importante destacar aqui a diferença entre as funções de ranking que veremos aqui e a muito utilizada função ORDER BY.
Enquanto ORDER BY apenas reordena as colunas com base nos valores, RANK() atribui uma nova coluna à tabela com a numeração das posições de cada linha no ranking.
A outra diferença é no caso de empates entre linhas. Nesses casos, ORDER apenas ordena os empatados com base em um critério, já RANK() atribui números iguais aos empatados e pula as posições seguintes (se há dois empatados em segundo lugar, o próximo número será 4, e não 3).
Exemplo prático
Obs.: Estamos usando aqui a base de dados que apresentamos em nosso minicurso sobre SQL.
Primeiro, vamos selecionar todos os dados da nossa tabela clientes:
SELECT * FROM clientes;
Agora vamos focar na coluna numérica Renda_Anual para nossa análise.
Com o comando abaixo, estamos selecionando algumas das colunas relevantes da tabela e aplicando a função RANK():
SELECT nome, email, renda_anual, RANK () OVER(ORDER BY renda_anual desc) AS posicao FROM clientes;Basicamente, a função RANK() aqui está criando uma coluna chamada posicao em cima (OVER) da informação de renda aual em ordem descresente (desc).
Vejam o resultado, que mostra não apenas as linhas ordenadas pela renda, mas também as posições de cada uma:

E note o que acontece nos casos de empate.
Nesse caso, se dois clientes tiverem a mesma renda, eles receberão a mesma posição no ranking, e a numeração seguinte será ajustada de acordo.
Função DENSE_RANK()
Vamos executar o mesmo exemplo utilizando DENSE_RANK().
SELECT nome, email, renda_anual, DENSE_RANK () OVER(ORDER BY renda_anual desc) AS posicao FROM clientes;
Diferença entre RANK() e DENSE_RANK()
A principal diferença entre RANK() e DENSE_RANK() está na numeração atribuída a registros empatados. Enquanto RANK() pula os números, DENSE_RANK() segue uma sequência contínua.
O ranking segue sem lacunas: clientes com a mesma renda compartilham a posição, mas a numeração segue contínua para os demais registros.
Resumo da Aula 1
As funções de janela são ferramentas poderosas para análise de dados em SQL. Neste primeiro episódio, aprendemos como criar rankings de registros ordenados utilizando RANK() e DENSE_RANK(), e entendemos as diferenças entre elas.
Nos próximos episódios, exploraremos outras funções de janela, como ROW_NUMBER(), SUM() OVER(), e AVG() OVER(), para aprofundar ainda mais a análise de dados.
Aula 2 - Enésimo maior valor com ROW_NUMBER()
Nesta aula vamos aprender a encontrar o N-ésimo maior valor com a função ROW_NUMBER(), identificando a linha ou registro em uma ordem específica.
Vamos fazer isso encontrando o segundo maior salário da base de clientes, a mesma que utilizamos na aula anterior.
Pronto para levar suas análises a um novo nível e impressionar com consultas mais avançadas? Então, vamos lá!
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:
Não vamos te encaminhar nenhum tipo de SPAM! A Hashtag Treinamentos é uma empresa preocupada com a proteção de seus dados e realiza o tratamento de acordo com a Lei Geral de Proteção de Dados (Lei n. 13.709/18). Qualquer dúvida, nos contate.
Função ROW_NUMBER()
A função ROW_NUMBER() traz a posição de cada um dos membros da lista atribuindo uma nova coluna, assim como as funções que vimos na aula anterior. Dessa vez ela vai trazer qual a posição de cada uma das linhas de acordo com um critério. A diferença de rank é que não são considerados empates, se alguns itens empatam a ordem continua sendo aplicada, sem repetir os números de ranqueamento.
Exemplo de aplicação
Vamos começar selecionando algumas informações específicas de nossa base de clientes e aplicando a função row_number() com renda anual decrescente como critério e nomeando a nova coluna como posicao. A estrutura vai ficar bem parecida com a da aula anterior.
select * from clientes;
select
nome, email, renda_anual, row_number() over(order by renda_anual desc_ as posicao
from clientes;Veja que o resultado também é parecido, mas sem repetir números na coluna posicao, e sim considerando os empates como elementos ordenados.

Filtrando o resultado com subquery
Nosso objetivo aqui é encontrar o segundo maior salário. A princípio, podemos pensar em fazer isso usando a cláusula where posicao = 2;. Mas isso não é possível, porque segundo a lógica do SQL, no nosso código a função de janela aconteceria depois de WHERE. Aassim, a coluna posicao, criada com a função de janela, não poderia ser referenciada pela cláusula WHERE.
Para filtrar os resultados de funções de janela, como ROW_NUMBER(), precisamos usar uma subquery.
A lógica da consulta é a mesma, a mudança vai ser que vamos colocar todo o código dentro de um select * from e guardar a tabela dessa consulta como resultado.
select * from (
select
nome, email, renda_anual, row_number() over(order by renda_anual desc_ as posicao
from clientes
) as resultado
where posicao = 2;E agora sim vamos encontrar o nosso segundo colocado.

Subquery com a função RANK()
Vamos demonstrar que a mesma lógica de subquery também é aplicável a um caso de RANK(), função que aprendemos anteriormente. Mas vamos passar o número 3 na cláusula WHERE, para ver como ele lida com um empate.
select * from (
select
nome, email, renda_anual, rank() over(order by renda_anual desc_ as posicao
from clientes
) as resultado
where posicao = 3;Aqui vamos ver dois clientes como resultado, já que RANK() permite empates no ranqueamento:

Resumo da Aula 2
Na nossa segunda aula, aprendemos o conceito de subquery e como é possível armazenar uma tabela resultante de uma consulta. A partir disso, vimos os diferentes resultados suscitados pela função RANK() e pela nova função que aprendemos agora, ROW_NUMBER(), que não permite empates no ranking.
Aula 3 - Médias móveis com AVG()
Nesta aula, vamos explorar como calcular médias móveis usando a função AVG(), uma técnica essencial para análises temporais e tendências em bancos de dados.
Vamos aplicar esse conceito para analisar a variação de salários na base de clientes, a mesma utilizada na aula anterior.
Pronto para aprimorar suas consultas SQL e tornar suas análises ainda mais estratégicas? Então, vamos lá!
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:
Não vamos te encaminhar nenhum tipo de SPAM! A Hashtag Treinamentos é uma empresa preocupada com a proteção de seus dados e realiza o tratamento de acordo com a Lei Geral de Proteção de Dados (Lei n. 13.709/18). Qualquer dúvida, nos contate.
O que são médias móveis?
As médias móveis são uma técnica estatística amplamente utilizada para analisar o comportamento de valores ao longo do tempo. Em vez de observar os dados mês a mês ou ponto a ponto, essa abordagem permite suavizar variações e identificar tendências de forma mais clara.
Um exemplo clássico do uso de médias móveis está no mercado de ações, onde investidores acompanham o desempenho de um ativo ao longo do tempo sem serem influenciados por oscilações pontuais. Da mesma forma, empresas podem aplicá-las para analisar tendências de vendas, preços de produtos ou até mesmo o desempenho de campanhas de marketing.
Com a função AVG(), podemos calcular médias móveis diretamente no SQL, tornando nossas análises mais estratégicas e previsíveis. Vamos ver na prática como aplicar esse conceito!
Exemplo prático
Para entender o comportamento das vendas ao longo do tempo, podemos calcular a média da receita dos últimos três meses. Isso nos fará ver tendências de crescimento ou queda sem depender de valores individuais, suavizando variações muito pontuais.
Apresentando os dados
Vamos começar examinando os dados disponíveis na tabela vendas:
SELECT * FROM vendas;
Essa tabela contém registros de vendas diárias entre janeiro e dezembro de 2019, oferecendo um panorama completo do desempenho comercial ao longo do ano.
Organizando os dados
Como queremos calcular a média móvel trimestral, primeiro precisamos organizar os dados para visualizar a receita total de cada mês. Mas a tabela não possui uma coluna específica para os meses, então precisaremos fazer uma consulta que exiba o total de vendas por mês, garantindo que os dados estejam ordenados corretamente de janeiro a dezembro.
select
date_format(data_venda, 'Y%-%m') as mes,
sum(receita_venda) as total_receita_mes
from vendas
group by date_format(data_venda, '%Y-%m')
order by mes;Primeiro, a função DATE_FORMAT(data_venda, '%Y-%m') transforma as datas das vendas no formato "ano-mês", agrupando as vendas dentro de cada mês específico. Em seguida, SUM(receita_venda) calcula o total de receita para cada um desses meses.
O agrupamento ocorre por meio da cláusula GROUP BY DATE_FORMAT(data_venda, '%Y-%m'), garantindo que os valores sejam somados corretamente dentro de cada período mensal.
Por fim, o ORDER BY mes organiza os resultados em ordem cronológica, permitindo uma análise clara da evolução das vendas ao longo do tempo.

Agora que temos os valores mensais, podemos aplicar uma função de janela para calcular a média móvel e entender melhor as tendências desse período.
Usando a função AVG() para calcular as médias móveis
Para calcular a média móvel da receita de vendas a cada três meses, precisamos somar os valores de cada trimestre e dividir por três. Isso nos permite suavizar variações mensais e identificar tendências de forma mais clara.
Podemos fazer isso utilizando a função de janela AVG(), que calculará a média das vendas do mês atual e dos dois meses anteriores. Para isso, vamos criar uma nova coluna chamada media_movel_3meses, aplicando a função AVG() sobre a soma da receita de vendas.
A consulta SQL abaixo implementa essa lógica:
SELECT
date_format(data_venda, '%Y-%m') as mes,
sum(receita_venda) as total_receita_mes,
avg(sum(receita_venda)) OVER (
ORDER BY date_format(data_venda, '%Y-%m')
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) as media_movel_3meses
FROM vendas
GROUP BY date_format(data_venda, '%Y-%m')
ORDER BY mes;Aqui, a função AVG() é usada como uma função de janela, calculando a média móvel considerando a receita do mês atual e dos dois anteriores. Isso significa que, para cada linha da tabela resultante, a nova coluna media_movel_3meses exibirá a média da receita de três meses consecutivos.

Com essa abordagem, conseguimos acompanhar as variações no desempenho das vendas ao longo do tempo sem nos prender a valores individuais, tornando a análise mais robusta e útil para tomada de decisões.
Resumo da Aula 3
Nesta aula, aprendemos o conceito de médias móveis e sua aplicação prática para analisar séries temporais de dados, como a receita de vendas. Essa bordagem serve para identificar tendências mais claras ao calcular a média de um conjunto de meses consecutivos.
Utilizamos a função AVG() como uma função de janela, que, ao considerar o mês atual e os dois anteriores, fornece uma visão consolidada do desempenho ao longo do tempo. Também demonstramos a importância de formatar as datas com DATE_FORMAT para agrupar os dados por mês, organizando a análise de maneira cronológica.
Aula 4 - Comparar Valores com LAG() e LEAD()
Nesta quarta aula vamos falar sobre comparação de valores utilizando as funções LAG() e LEAD(), que são essenciais para análises como Month-over-Month (MoM) e Year-over-Year (YoY).
Se você quer entender como comparar períodos e identificar tendências, fica até o final desta aula! E já comece deixando seu like, se inscrevendo no canal e ativando o sino de notificação para não perder nenhum conteúdo novo que sai toda semana. Vamos lá!
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:
Não vamos te encaminhar nenhum tipo de SPAM! A Hashtag Treinamentos é uma empresa preocupada com a proteção de seus dados e realiza o tratamento de acordo com a Lei Geral de Proteção de Dados (Lei n. 13.709/18). Qualquer dúvida, nos contate.
O que são Análises MoM e YoY?
Antes de mergulharmos nas funções, é importante entender o que são análises Month-over-Month (MoM) e Year-over-Year (YoY). Essas análises consistem em comparar valores de diferentes períodos para identificar crescimento, queda ou tendências. Por exemplo:
- MoM (Month-over-Month): Comparar as vendas de agosto com as de julho para ver se houve aumento ou redução.
- YoY (Year-over-Year): Comparar as vendas de agosto de 2023 com as de agosto de 2022 para avaliar o desempenho ao longo do tempo.
Essas análises são úteis para entender o impacto de campanhas, sazonalidades ou mudanças estratégicas.
Por exemplo, se em agosto você fez uma campanha de Dia dos Pais e as vendas dispararam, comparar com julho pode não ser justo. Nesse caso, faz mais sentido comparar agosto de 2023 com agosto de 2022, quando a mesma campanha foi realizada.
Função LAG(): Comparando Valores com Períodos Anteriores
A função LAG() é útil para fazer essas comparações que acabamos de citar. Ela permite acessar o valor de uma linha anterior dentro de uma janela de dados. Vamos ver um exemplo prático para entender como isso funciona.
Imagine que temos uma tabela chamada vendas que compila todas as vendas dia a dia desde janeiro e 2019 até dezembro de 2019.

Vamos ver como comparar as vendas de cada mês com as do mês anterior. Por exemplo, março com fevereiro.
Para isso, primeiro precisamos agregar as vendas por mês:
select
date_format(data_venda, '%Y-%m') as mes,
sum(qtd_vendida) as total_vendido_mes
from vendas
group by date_format(data_venda, '%Y-%m')
order by mes;Agora nós temos uma seleção que agrupa todas as vendas do ano por mês.

Agora, vamos usar uma CTE (Common Table Expression), que é uma tabela temporária, para armazenar os dados mensais da tabela acima.
with vendas_mensais as (
select
date_format(data_venda, '%Y-%m') as mes,
sum(qtd_vendida) as total_vendido_mes
from vendas
group by date_format(data_venda, '%Y-%m')
order by mes
)Agora nós temos uma “nova tabela” chamada vendas_mensais.
Vamos fazer uma consulta dos meses e totais vendidos a partir dessa CTE para então utilizar a função LAG().
select
mes,
total_vendido_mes,
lag(total_vendido_mes, 1) over (order by mes) as vendas_mes_anterior
from vendas_mensais;Neste exemplo, a função LAG() retorna o valor de total_vendido_mes da linha anterior (definido pelo argumento 1). Se não houver um valor anterior (como no caso do primeiro mês), o resultado será NULL.

Personalizando a Função LAG()
A função LAG() aceita três argumentos:
- Valor a ser comparado: No nosso caso, total_vendido_mes.
- Número de linhas para "voltar": Por padrão, é 1 (linha anterior), mas você pode comparar com 2, 3 ou até 12 meses atrás.
- Valor padrão para NULL: Se não houver um valor anterior, você pode definir um valor padrão, como 0.
Por exemplo, para comparar com 12 meses atrás (análise YoY), faríamos:
lag(total_vendido_mes, 12, 0) over (order by mes) as vendas_ano_anteriorAgora, cada mês será comparado com o mesmo mês do ano anterior.
Fazendo análises comparativas mês a mês
Com os valores anteriores em mãos, podemos fazer um cálculo comparativo. Por exemplo, para calcular a diferença MoM:
select
mes,
total_vendido_mes,
lag(total_vendido_mes, 1, 0) over (order by mes) as vendas_mes_anterior,
total_vendido_mes - lag(total_vendido_mes) over (order by mes) as diferenca
from vendas_mensais
order by mes;
Função LEAD(): Comparando com Períodos Futuros
Além da LAG(), temos a função LEAD(), que faz o oposto: ela acessa valores de linhas futuras. Por exemplo, para comparar as vendas de um mês com o próximo:
select
mes,
total_vendido_mes,
lead(total_vendido_mes, 1) over (order by mes) as vendas_mes_seguinte
from vendas_mensais
order by mes;Embora menos comum, a LEAD() pode ser útil em cenários específicos, como previsões ou análises de tendências.
Resumo da Aula 4
Nesta aula, aprendemos como usar as funções LAG() e LEAD() para comparar valores em diferentes períodos, essencial para análises MoM e YoY. Com essas ferramentas, você pode identificar tendências, avaliar o impacto de campanhas e tomar decisões mais informadas.
Aula 5 - Somas Acumuladas com SUM()
Nesta quinta aula da nossa série de análise de dados com funções de janela no SQL, vamos falar sobre somas acumuladas utilizando a função SUM().
Essa técnica é essencial para acompanhar o crescimento de valores ao longo do tempo, como vendas acumuladas mês a mês. Preparado para aprender mais SQL?
Vamos lá!
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:
Não vamos te encaminhar nenhum tipo de SPAM! A Hashtag Treinamentos é uma empresa preocupada com a proteção de seus dados e realiza o tratamento de acordo com a Lei Geral de Proteção de Dados (Lei n. 13.709/18). Qualquer dúvida, nos contate.
O que é Soma Acumulada?
A soma acumulada é uma técnica que permite somar valores sequencialmente, acumulando os resultados à medida que avançamos no tempo. Por exemplo:
- Em janeiro, você tem 100 vendas. O acumulado é 100.
- Em fevereiro, você tem 50 vendas. O acumulado passa a ser 150 (100 + 50).
- Em março, você tem 80 vendas. O acumulado passa a ser 230 (150 + 80).
Essa análise é muito útil para acompanhar o crescimento de métricas como vendas, receitas ou qualquer outro indicador ao longo do tempo.
Visualizando a Tabela de Vendas
Vamos trabalhar com a tabela de vendas que registra as vendas dia a dia, aquela já utilizamos em aulas anteriores.

Para facilitar, primeiro agrupamos as vendas por mês:
select
date_format(data_venda, '%y-%m') as mes,
sum(qtd_vendida) as total_vendido_mes
from vendas
group by date_format(data_venda, '%y-%m')
order by mes;Esse código retorna o total de vendas para cada mês.

Criando uma CTE para Organizar os Dados
Para calcular a soma acumulada, usaremos mais uma vez uma CTE (Common Table Expression), que é uma tabela temporária para armazenar os dados mensais:
with vendas_mensais as (
select
date_format(data_venda, '%y-%m') as mes,
sum(qtd_vendida) as total_vendido_mes
from vendas
group by date_format(data_venda, '%y-%m')
order by mes
)Agora, temos uma "tabela" chamada vendas_mensais com os totais de vendas por mês.
Calculando a Soma Acumulada com SUM()
Com a CTE pronta, vamos usar a função SUM() como uma função de janela para calcular o acumulado:
select
mes,
total_vendido_mes,
sum(total_vendido_mes) over (order by mes) as acumulado
from vendas_mensais
order by mes;Aqui, a função SUM() soma os valores de total_vendido_mes de forma acumulada, mês a mês. O resultado será:

Conferindo o Total
Para garantir que o cálculo está correto, podemos conferir o total de vendas com uma consulta simples:
select sum(qtd_vendida) as total_vendido
from vendas;Se o valor final do acumulado for igual ao total de vendas, o cálculo está correto!
Resumo da Aula 5
Nesta aula, aprendemos a calcular somas acumuladas usando a função SUM() como uma função de janela no SQL. Com essa técnica, você pode acompanhar o crescimento de métricas ao longo do tempo, como vendas acumuladas mês a mês.
Essa análise é poderosa para identificar tendências e tomar decisões mais informadas.
Aula 6 - Percentuais Acumulados para Análise de Pareto
Na sexta aula da nossa série de análise de dados com funções de janela no SQL, vamos explorar percentuais acumulados e como utilizá-los para realizar uma análise de Pareto. Essa técnica é essencial para identificar quais elementos (como produtos, clientes ou categorias) contribuem mais para um resultado específico, como receita ou vendas. Preparado para descobrir como aplicar isso no SQL?
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:
Não vamos te encaminhar nenhum tipo de SPAM! A Hashtag Treinamentos é uma empresa preocupada com a proteção de seus dados e realiza o tratamento de acordo com a Lei Geral de Proteção de Dados (Lei n. 13.709/18). Qualquer dúvida, nos contate.
O que é a Análise de Pareto?
A análise de Pareto é baseada no Princípio de Pareto, também conhecido como a regra 80/20. Esse princípio afirma que, em muitos casos, 80% dos resultados vêm de 20% dos esforços. Por exemplo:
- 80% da receita de uma empresa pode vir de 20% dos produtos.
- 80% das vendas podem ser geradas por 20% dos clientes.
Com essa análise, podemos identificar quais elementos são os mais relevantes e focar nossos esforços neles.
Visualizando a Base de Dados
Vamos utilizar duas tabelas para essa análise:
- produtos: Contém informações como ID_produto, nome_produto e preco_unitario.
- vendas: Registra as vendas, com colunas como ID_venda, ID_produto e receita_venda.

O objetivo é calcular o percentual acumulado da receita gerada por cada produto, ordenando-os do maior para o menor contribuidor.
Passo 1: Calculando o Total de Receita por Produto
Primeiro, precisamos calcular o total de receita gerado por cada produto. Para isso, vamos usar um JOIN para relacionar as tabelas produtos e vendas e, em seguida, agrupar os resultados por produto:
select
id_produto,
nome_produto,
sum(receita_venda) as total_receita
from produtos
left join vendas on produtos.id_produto = vendas.id_produto
group by produtos.id_produto, produtos.nome_produto
order by total_receita desc;Esse código retorna o total de receita para cada produto, ordenado do maior para o menor.
Passo 2: Calculando o Percentual Acumulado
Agora, vamos calcular o percentual acumulado da receita. Para isso, usaremos uma subquery e a função de janela SUM() com a cláusula OVER:
select
nome_produto, total_receita,
(sum(total_receita) over(order by total_receita desc) / sum(total_receita) over() * 100 percentual_acumulado
from (
select
id_produto,
nome_produto,
sum(receita_venda) as total_receita
from produtos
left join vendas on produtos.id_produto = vendas.id_produto
group by produtos.id_produto, produtos.nome_produto
order by total_receita desc;Explicação do Código:
- Subquery: Calcula o total de receita por produto.
- SUM() OVER (ORDER BY total_receita DESC): Calcula a soma acumulada da receita, ordenada do maior para o menor.
- SUM() OVER (): Calcula o total geral de receita.
- Percentual Acumulado: Divide a soma acumulada pelo total geral e multiplica por 100 para obter o percentual.
Resultado da Análise
Ao executar o código, teremos uma tabela como esta:

Interpretação:
- O Headphone Bluetooth contribui com 91% da receita total.
- Juntando o Headphone e a Cadeira Gamer, temos 96% da receita.
- Os 4 produtos juntos representam 100% da receita.
Essa análise nos mostra que um pequeno número de produtos (no caso, o Headphone Bluetooth) é responsável pela maior parte da receita.
Aplicações Práticas da Análise de Pareto
- Foco em Produtos ou Clientes: Identificar quais produtos ou clientes geram mais receita e priorizá-los.
- Otimização de Estoque: Concentrar esforços nos produtos mais vendidos.
- Tomada de Decisão Estratégica: Direcionar investimentos para os elementos que geram maior retorno.
Resumo da Aula 6
Nesta aula, aprendemos a calcular percentuais acumulados usando funções de janela no SQL e aplicamos essa técnica para realizar uma análise de Pareto. Com isso, você pode identificar quais elementos contribuem mais para seus resultados e tomar decisões mais informadas.
Aula 7 - Categorização de Valores com NTILE
Na sétima aula da nossa série, vamos explorar mais uma aplicação prática das funções de janela: a categorização de valores usando NTILE.
Essa técnica é ideal para dividir dados em grupos (como faixas de renda, desempenho ou vendas) e tomar decisões estratégicas com base nessa segmentação.
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:
Não vamos te encaminhar nenhum tipo de SPAM! A Hashtag Treinamentos é uma empresa preocupada com a proteção de seus dados e realiza o tratamento de acordo com a Lei Geral de Proteção de Dados (Lei n. 13.709/18). Qualquer dúvida, nos contate.
O que é NTILE?
NTILE é uma função que divide os dados em quantis (grupos com valores semelhantes).
Por exemplo:
- Criar 4 grupos de clientes com renda semelhante.
- Classificar produtos em faixas de desempenho (alto, médio, baixo).
A regra é simples: NTILE(N) divide os dados em N partes iguais (ou quase iguais).
Visualizando a base de dados

Usaremos a tabela clientes, que tem diversas colunas, mas entre elas iremos destacar a coluna Renda_Anual, que é onde faremos a divisão em quantis.
Aplicando NTILE para criar faixas de renda
Vamos dividir os clientes em 4 faixas (quartis), onde 1 = maior renda e 4 = menor renda:
select
id_cliente,
nome,
renda_anual,
ntile(4) over (order by renda_anual desc) as faixa_renda
from clientes;Explicação:
- NTILE(4): Divide em 4 grupos.
- OVER (ORDER BY renda_anual DESC): Ordena pela renda (do maior para o menor).
Resultado e interpretação
Insights:
- Clientes da faixa 1 (top 25%) concentram as maiores rendas.
- A faixa 4 agrupa os clientes com menor renda, permitindo estratégias específicas (ex.: promoções para esse grupo).
Aplicações práticas
- Segmentação de clientes para campanhas de marketing.
- Análise de desempenho de produtos/vendedores (ex.: top 10%, médio 80%, baixo 10%).
- Distribuição de recursos com base em faixas (ex.: investir mais nos clientes do grupo 1).
Resumo da Aula 7
Nesta aula, aprendemos a usar NTILE para criar categorias automáticas em SQL, uma ferramenta simples mas poderosa para tomada de decisões baseada em dados.
Aula 8 - Funções MAX() e MIN()
Nesta aula, vamos explorar como identificar valores máximos e mínimos dentro de uma janela de dados utilizando as funções MAX() e MIN() no SQL. Essa abordagem é especialmente útil para análises comparativas em intervalos específicos, como meses consecutivos, permitindo identificar tendências e outliers.
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:
Não vamos te encaminhar nenhum tipo de SPAM! A Hashtag Treinamentos é uma empresa preocupada com a proteção de seus dados e realiza o tratamento de acordo com a Lei Geral de Proteção de Dados (Lei n. 13.709/18). Qualquer dúvida, nos contate.
Diferença entre MAX/MIN simples e funções de janela
Enquanto as funções MAX() e MIN() tradicionais retornam o maior e o menor valor de uma coluna inteira, a versão com janelas (OVER) permite calcular esses valores dentro de um intervalo dinâmico, como os últimos 3 meses, por exemplo.
Exemplo Prático: Vendas Mensais
Vamos usar uma tabela de vendas onde cada registro representa uma transação em uma data específica.

Nosso objetivo é:
- Agrupar vendas por mês para obter o total vendido.
- Aplicar
MAX()eMIN()em janelas móveis para comparar períodos.
Passo 1: Agrupando vendas por mês
Primeiro, agrupamos as vendas por mês usando GROUP BY:
select
date_format(data_venda, '%Y-%m') as mes,
sum(qtd_vendida) as total_vendido_mes,
from vendas
group my date_format(data_venda, '%Y-%m')
ORDER BY mes;Isso retornará uma tabela com o total vendido a cada mês.

Passo 2: Aplicando MAX() em uma janela de 3 meses
Agora, queremos saber, para cada mês, qual foi a maior venda nos últimos 3 meses. Usamos a função de janela:
select
mes,
total_vendido_mes,
max(total_vendido_mes) over (
order by mes
rows between 2 preceding and current row
) as max_vendas_3_meses
from vendas
group by mes
order by mes;Explicação:
ROWS BETWEEN 2 PRECEDING AND CURRENT ROWdefine a janela como o mês atual + os 2 anteriores.- Se um mês não tiver 2 meses anteriores (como Janeiro), o máximo será apenas o valor dele mesmo.

Passo 3: Aplicando MIN() na mesma janela
Podemos fazer o mesmo para o mínimo, trocando MAX() por MIN():
select
mes,
total_vendido_mes,
MIN(total_vendido_mes) over (
order by mes
rows between 2 preceding and current row
) as max_vendas_3_meses
from vendas
group by mes
order by mes;Quando usar?
- Identificar picos e quedas em vendas.
- Comparar desempenho em períodos específicos.
- Detectar anomalias (ex.: um mês com vendas muito abaixo da média dos últimos meses).
Resumo da Aula 8
Nesta aula, vimos como:
✔ Agrupar dados por períodos (ex.: meses).
✔ Aplicar MAX() e MIN() em janelas móveis para comparações.
✔ Definir intervalos personalizados (ROWS BETWEEN X PRECEDING AND Y FOLLOWING).
Essa técnica é poderosa para análises temporais e pode ser combinada com outras funções de janela, como AVG() para médias móveis, vistas em aulas anteriores.
Aula 9 - Percentual de Contribuição
Nesta penúltima aula da nossa série sobre funções de janela no SQL, vamos explorar como calcular a contribuição percentual de cada registro em relação ao total.
Essa técnica é essencial para identificar quais elementos (como meses, produtos ou clientes) têm maior impacto nos resultados globais.
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:
Não vamos te encaminhar nenhum tipo de SPAM! A Hashtag Treinamentos é uma empresa preocupada com a proteção de seus dados e realiza o tratamento de acordo com a Lei Geral de Proteção de Dados (Lei n. 13.709/18). Qualquer dúvida, nos contate.
O que é Análise de Contribuição Percentual?
Imagine que sua empresa teve uma receita total de R$100.000 em um ano.
Se um único cliente contribuiu com R$30.000, isso significa que ele representa 30% do faturamento.
Com funções de janela, podemos calcular esse percentual de forma dinâmica, sem precisar agrupar manualmente os dados.
Exemplo Prático: Participação Percentual das Vendas Mensais
Vamos usar uma tabela de vendas para calcular:
- O total vendido por mês.
- A contribuição percentual de cada mês em relação ao total anual.

Passo 1: Agrupando Vendas por Mês
Primeiro, agrupamos as vendas por mês usando GROUP BY:
select
date_format(data_venda, '%Y-%m') as mes,
sum(qtd_vendida) as total_vendido_mes
from vendas
group my date_format(data_venda, '%Y-%m')Isso retorna uma tabela com o total vendido em cada mês.
Passo 2: Calculando o Total Geral com Função de Janela
Para comparar cada mês com o total anual, usamos uma função de janela sem filtros, somando todos os registros:
select
date_format(data_venda, '%Y-%m') as mes,
sum(qtd_vendida) as total_vendido_mes,
sum(sum(Qtd_Vendida)) over() as total_geral
from vendas
group my date_format(data_venda, '%Y-%m')
Passo 3: Calculando o Percentual de Contribuição
Agora, dividimos o total do mês pelo total geral e multiplicamos por 100 para obter a porcentagem:
select
date_format(data_venda, '%Y-%m') as mes,
sum(qtd_vendida) as total_vendido_mes,
sum(sum(Qtd_Vendida)) over() *100 as total_geral
from vendas
group my date_format(data_venda, '%Y-%m')Exemplo de Saída:
| Mês | Total Vendido | Percentual |
|---|---|---|
| 2019-01 | 101 | 27% |
| 2019-12 | 36 | 9.6% |
| ... | ... | ... |
Quando Usar?
✔ Identificar os maiores contribuintes (ex.: clientes que geram 80% da receita).
✔ Comparar desempenho entre períodos (ex.: qual mês teve maior impacto nas vendas?).
✔ Análise de Pareto (20% dos produtos geram 80% do faturamento).
Resumo da aula 9
Nesta aula, aprendemos:
✅ Como calcular o total geral usando SUM() OVER ().
✅ Como transformar valores absolutos em percentuais.
✅ Como ordenar resultados para identificar os maiores contribuintes.
Essa técnica é poderosa para tomada de decisões estratégicas, permitindo focar nos elementos que mais impactam seus resultados.
Aula 10 - Análises segmentadas com PARTITION BY
Na décima e última aula da nossa série sobre funções de janela no SQL, vamos explorar o comando PARTITION BY, uma ferramenta poderosa para análises segmentadas.
Com ele, você pode dividir dados em grupos (como marcas de produtos) e aplicar cálculos independentes, como rankings ou agregações, dentro de cada grupo.
Essa técnica é ideal para análises detalhadas que impulsionam decisões estratégicas.
Caso prefira esse conteúdo no formato de vídeo-aula, assista ao vídeo abaixo ou acesse o nosso canal do YouTube!
Para fazer o download do(s) arquivo(s) utilizados na aula, preencha com o seu e-mail:
Não vamos te encaminhar nenhum tipo de SPAM! A Hashtag Treinamentos é uma empresa preocupada com a proteção de seus dados e realiza o tratamento de acordo com a Lei Geral de Proteção de Dados (Lei n. 13.709/18). Qualquer dúvida, nos contate.
O que é PARTITION BY?
O PARTITION BY é um comando usado em funções de janela no SQL para dividir os dados em partições (grupos) com base em uma coluna, como marca ou região.
Dentro de cada partição, a função de janela (ex.: RANK(), SUM(), AVG()) é aplicada de forma independente, permitindo análises segmentadas sem agregar os dados.
Exemplo:
- Sem PARTITION BY: Um ranking de preços considera todos os produtos juntos.
- Com PARTITION BY: Você cria rankings separados para cada marca, como "os produtos mais caros da Dell".
Visualizando a base de dados
Usaremos a tabela produtos, que contém colunas como nome_produto, marca_produto e preco_unitario. Nosso objetivo é criar um ranking de preços segmentado por marca.

Aplicando PARTITION BY para criar rankings por marca
Primeiro, vejamos um ranking geral de produtos por preço:
SELECT
nome_produto,
preco_unitario,
RANK() OVER (ORDER BY preco_unitario DESC) AS ranking_preco
FROM produtos;
Agora, usamos PARTITION BY para criar um ranking segmentado por marca:
SELECT
nome_produto,
marca_produto,
preco_unitario,
RANK() OVER (
PARTITION BY marca_produto
ORDER BY preco_unitario DESC
) AS ranking_por_marca
FROM produtos
ORDER BY marca_produto, preco_unitario DESC;Explicação:
- PARTITION BY marca_produto: Divide os dados em grupos por marca (ex.: Dell, Altura, AKG).
- ORDER BY preco_unitario DESC: Dentro de cada partição, ordena do mais caro ao mais barato.
- RANK(): Atribui uma posição dentro de cada grupo.
- ORDER BY marca_produto, preco_unitario DESC: Organiza o resultado por marca e preço.

Resumo da Aula 10
Nesta aula, aprendemos:
- ✔ Como usar PARTITION BY para dividir dados em grupos e aplicar cálculos independentes.
- ✔ Criar rankings segmentados, como preços de produtos por marca.
- ✔ Comparar rankings gerais versus particionados.
- ✔ Combinar PARTITION BY com outras funções de janela (ex.: RANK(), SUM()) para análises avançadas.
O PARTITION BY é uma ferramenta simples, mas poderosa, para análises segmentadas no SQL.
Com esta aula, encerramos nossa série de 10 aulas sobre funções de janela, equipando você com técnicas práticas para análises de dados no mercado de trabalho.
Perguntas frequentes
1. Para que serve a cláusula OVER() no SQL?
É ela que define a janela, ou seja, o conjunto de linhas considerado no cálculo de cada resultado. Dentro do OVER você usa PARTITION BY para dividir os dados em grupos e ORDER BY para definir a ordem, base para rankings, médias móveis e somas acumuladas.
2. Qual a diferença entre RANK() e DENSE_RANK()?
As duas classificam as linhas na ordem definida, mas tratam empates de forma diferente. O RANK() pula posições: com dois empatados em segundo lugar, o próximo recebe a quarta posição. Já o DENSE_RANK() mantém a sequência contínua, e o próximo colocado recebe a terceira posição.
3. Qual a diferença entre funções de janela e GROUP BY?
O GROUP BY resume as linhas e devolve um registro por grupo, então o detalhe original se perde. A função de janela calcula o mesmo tipo de agregação, mas devolve o valor em cada linha, ao lado dos dados originais, o que permite comparar o item com o total do grupo.
4. Para que serve o PARTITION BY nas funções de janela?
Ele segmenta o cálculo por categoria, reiniciando a janela a cada grupo. Com PARTITION BY por marca, por exemplo, o ranking começa do zero em cada marca, em vez de classificar a tabela inteira de uma vez. É o recurso que permite análises comparativas dentro de cada segmento.
Conclusão da Série
Ao longo dessas 10 aulas, exploramos as principais funções de janela no SQL e suas aplicações práticas em análises de dados. Vimos como utilizar ferramentas como RANK(), ROW_NUMBER(), LAG(), LEAD(), AVG(), SUM(), NTILE() e outras para responder perguntas complexas de negócio com mais precisão e eficiência.
De rankings e médias móveis a análises de Pareto e percentuais de contribuição, cada aula trouxe um passo a mais para dominar a análise de dados com SQL de forma clara e aplicada. Agora você tem em mãos uma ferramenta poderosa para transformar dados em insights!
Hashtag Treinamentos
Para acessar outras publicações de SQL, clique aqui!
Posts mais recentes de SQL
- UPDATE em SQL: guia completo para usar o comando sem cometer errosUPDATE em SQL: entenda como atualizar dados com segurança, sintaxe, exemplos práticos e cuidados para evitar erros comuns.
- SQL DELETE: como usar o comando para excluir dados?SQL DELETE: entenda como excluir registros, usar a sintaxe correta e evitar erros ao remover dados de tabelas em bancos SQL.
- Guia completo para desenvolvedor SQL: o que faz, salário e como aprenderConheça as funções do desenvolvedor SQL, salários médios, como começar na área e como está o atual mercado de trabalho.
Posts mais recentes da Hashtag Treinamentos
- Planilha de Controle de Notas Fiscais no Excel [Grátis]Baixe a planilha de controle de notas fiscais no Excel grátis: calcule ISS e retenções, veja o que está em aberto e gere a cobrança de cada nota de serviço.
- Qual IA usar na empresa: ChatGPT, Claude ou Perplexity?Qual IA usar na empresa: veja as diferenças entre ChatGPT, Claude e Perplexity e quando cada um rende mais em cada área da sua equipe.
- Apostilas Gratuitas em PDF: Excel, Power BI, Python e IABaixe apostilas gratuitas em PDF de Excel, Power BI, Python, Claude e agentes de IA, com exercícios e gabarito. Escolha a sua e comece hoje.








