Projetos
SQL · Análise · Desenvolvimento

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.

Nível Intermediário Ferramentas SQL · SQLite Tipo Análise de dados
Visão geral

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.

Passo a passo

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étricavalor
Pedidos entregues96.478
Receita totalR$ 13.221.498
Ticket médioR$ 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çãocategoriapctacumulado
health_beauty9,3%9,3%
watches_gifts8,9%18,1%
bed_bath_table7,6%25,8%
sports_leisure7,3%33,0%
computers_accessories6,7%39,7%
furniture_decor5,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:

UFpedidosreceita
SP40.501R$ 5.068.000
RJ12.350R$ 1.760.000
MG11.354R$ 1.552.000
RS5.345R$ 729.000
PR4.923R$ 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.

Resultado

O panorama visualizado

O que dá pra levar daqui

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).