Análise de Vendas — Como foi feito (explicado fácil)
Imagina que você é dono de uma loja online com 96 mil pedidos. Onde tá o seu dinheiro? Em qual categoria? Em qual estado? Em qual mês? Sem dados, é chute. Com SQL, é resposta em segundos.
O que é isso, em uma frase?
Peguei os dados reais de um e-commerce brasileiro (a Olist, que reúne lojinhas que vendem em marketplaces) — 96.478 pedidos entregues, somando R$ 13,2 milhões de receita — e respondi 5 perguntas-chave usando só SQL.
O que eu queria descobrir:
- Qual categoria de produto gera mais dinheiro?
- Quanto dessa receita está concentrada em poucas categorias?
- O faturamento está crescendo, parado ou caindo?
- Quais regiões do Brasil compram mais?
- Em qual dia da semana o brasileiro compra mais?
Tudo em SQL puro. Sem exportar pra planilha, sem Python — direto no banco. É mais rápido, mais reproduzível, e demonstra controle real da ferramenta.
Da pergunta ao gráfico
1 · Conhecer o tamanho do negócio. Antes de mergulhar nos detalhes, eu queria ter na cabeça os 3 números mais básicos: quantos pedidos, quanto de receita, qual o ticket médio. Esses números viram a "régua" das próximas análises.
| métrica | valor |
|---|---|
| Pedidos entregues | 96.478 |
| Receita total | R$ 13.221.498 |
| Ticket médio | R$ 152,18 |
2 · Descobrir quem é o "campeão de vendas". Quero a receita por categoria, mas também já quero ver quão concentrada ela está. É aí que entram as window functions — funções que "olham" várias linhas de uma vez. Aqui usei 3:
SUM() OVER ()— soma TUDO. Vira o denominador pra calcular percentual.SUM() OVER (ORDER BY receita DESC)— soma ACUMULADA. Vai mostrando quanto cada nova categoria adiciona ao total (45%, 50%, 55%...).RANK()— devolve a posição (1°, 2°, 3°...).
WITH receita_cat AS (
SELECT c.product_category_name_english AS categoria,
SUM(i.price) AS receita
FROM items i
JOIN products p ON p.product_id = i.product_id
LEFT JOIN cat c ON c.product_category_name = p.product_category_name
GROUP BY categoria
)
SELECT categoria, receita,
ROUND(100.0 * receita / SUM(receita) OVER (), 1) AS pct,
ROUND(100.0 * SUM(receita) OVER (ORDER BY receita DESC) / SUM(receita) OVER (), 1) AS pct_acumulado,
RANK() OVER (ORDER BY receita DESC) AS posicao
FROM receita_cat
ORDER BY receita DESC
LIMIT 8;
| posição | categoria | pct | acumulado |
|---|---|---|---|
| 1° | health_beauty | 9,3% | 9,3% |
| 2° | watches_gifts | 8,9% | 18,1% |
| 3° | bed_bath_table | 7,6% | 25,8% |
| 4° | sports_leisure | 7,3% | 33,0% |
| 5° | computers_accessories | 6,7% | 39,7% |
| 6° | furniture_decor | 5,4% | 45,1% |
Olha o que a coluna acumulado revela: as 5 maiores categorias juntas representam 40% da receita. Ou seja, se as outras 65 categorias somem amanhã, ainda sobra metade do faturamento. Concentração alta — bom pra focar promoções, ruim por risco.
3 · Ver se o negócio está crescendo. Aqui uso outra window function chamada LAG() — ela "olha pra trás" e pega o valor do mês anterior. Aí dá pra calcular a variação mês a mês (subiu? caiu?). Pelos números, descobri que novembro de 2017 foi o pico absoluto (R$ 987 mil) — provavelmente Black Friday.
4 · Mapear a geografia. Onde está esse dinheiro? Vou ver os top 5 estados:
| UF | pedidos | receita |
|---|---|---|
| SP | 40.501 | R$ 5.068.000 |
| RJ | 12.350 | R$ 1.760.000 |
| MG | 11.354 | R$ 1.552.000 |
| RS | 5.345 | R$ 729.000 |
| PR | 4.923 | R$ 666.000 |
São Paulo sozinho responde por 38% da receita. O Sudeste todo, por 63%. Faz sentido pensar a logística e o atendimento priorizando essas regiões.
O panorama visualizado
Em uma linha: o que esse projeto ensina
Que SQL bom não é só SELECT. Window functions transformam SQL numa ferramenta de análise séria — calcular percentual, ranking e variação na própria query, sem mexer em planilha, é um divisor de águas.
Coisas técnicas que apareceram aqui: WITH (CTE), JOIN múltiplos, SUM() OVER (), SUM() OVER (ORDER BY …) (soma acumulada), RANK(), LAG(), funções de data (strftime).