Projetos
SQL · Segmentação · Desenvolvimento

Segmentação RFM — Como foi feito (explicado fácil)

Imagina que você é dono de uma cafeteria. Tem cliente que vem todo dia, tem quem nunca mais voltou, tem quem gasta R$ 5 e tem quem gasta R$ 100. Tratar todo mundo igual é jogar dinheiro fora. RFM resolve isso — separa sua base em grupos por tipo de relacionamento.

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

O que é isso, em uma frase?

RFM é a sigla de três palavras que descrevem todo cliente:

  • Recência — "faz quanto tempo a última vez?". Cliente que comprou ontem vale mais que quem comprou há 2 anos.
  • Frequência — "quantas vezes comprou no total?". Quem volta sempre é ouro.
  • Monetário — "quanto gastou?". Sem polêmica.

Eu peguei os 93 mil clientes de um e-commerce real, calculei esses 3 números pra cada um e usei SQL pra "colocar nota de 1 a 5" em cada eixo. Depois traduzi as combinações em 6 grupos com nomes de negócio: Campeões, Fiéis, Em risco, Hibernando, e por aí vai.

Pra que serve? Pra marketing parar de mandar o mesmo e-mail pra todo mundo. Você fala com "Campeão" oferecendo VIP. Você fala com "Em risco" oferecendo desconto pra voltar. Cada grupo, sua estratégia.

Passo a passo

De 93 mil clientes a 6 grupos

1 · Calcular R, F e M de cada cliente. Antes de qualquer nota, eu preciso dos 3 números crus por pessoa. Aqui aparece um detalhe importante: "hoje" pra esse cálculo é a data do pedido mais recente da base, não a data real (porque os dados são antigos, de 2018). É a chamada "data de referência".

WITH base AS (
  SELECT cu.customer_unique_id AS cid,
         -- recência = "dias desde a última compra"
         julianday((SELECT MAX(order_purchase_timestamp) FROM orders))
            - julianday(MAX(o.order_purchase_timestamp)) AS recencia,
         COUNT(DISTINCT o.order_id)                      AS frequencia,
         SUM(pay.payment_value)                          AS monetario
  FROM orders o
  JOIN customers cu  ON cu.customer_id = o.customer_id
  JOIN payments  pay ON pay.order_id   = o.order_id
  WHERE o.order_status = 'delivered'
  GROUP BY cu.customer_unique_id
)

2 · Transformar números em "notas" com NTILE. Os números crus são difíceis de comparar (1 dia × 365 dias × R$ 50 × R$ 5.000). Resolvo isso com NTILE(5) — uma função que ordena todo mundo e divide em 5 grupos iguais. Cada cliente ganha uma nota de 1 a 5 em cada eixo. Cuidado com a ordem: quem comprou recente é melhor, então pra Recência uso ORDER BY recencia DESC (5 = mais recente).

scored AS (
  SELECT cid, recencia, frequencia, monetario,
         NTILE(5) OVER (ORDER BY recencia DESC)  AS r,  -- 5 = comprou recente
         NTILE(5) OVER (ORDER BY frequencia ASC) AS f,  -- 5 = compra muito
         NTILE(5) OVER (ORDER BY monetario ASC)  AS m   -- 5 = gasta muito
  FROM base
)

3 · Traduzir combinações em nomes de negócio. Aqui é a hora de pensar como marqueteiro, não como técnico. Cliente com R alta e F alta? Campeão. Cliente que era frequente mas sumiu? Em risco. Quem comprou uma vez e sumiu há séculos? Hibernando. Cada combinação ganha um rótulo:

SELECT CASE
         WHEN r >= 4 AND f >= 4 THEN 'Campeões'
         WHEN r >= 3 AND f >= 3 THEN 'Fiéis'
         WHEN r >= 4 AND f <= 2 THEN 'Novos / Promissores'
         WHEN r <= 2 AND f >= 3 THEN 'Em risco'
         WHEN r <= 2 AND f <= 2 THEN 'Hibernando / Perdidos'
         ELSE                        'Atenção'
       END                              AS segmento,
       COUNT(*)                         AS clientes,
       ROUND(AVG(monetario), 0)         AS ticket_medio
FROM scored
GROUP BY segmento
ORDER BY clientes DESC;

4 · O resultado. 93 mil pessoas viraram 6 grupos com tamanho e ticket médio claros:

segmentoclientesticket médio
Em risco21.947R$ 242
Fiéis18.730R$ 178
Hibernando / Perdidos15.397R$ 56
Campeões15.336R$ 307
Novos / Promissores14.401R$ 55
Atenção7.546R$ 55

Olha que história a tabela conta: Campeões têm o maior ticket (R$ 307) — vale a pena programa de fidelidade. Em risco são o maior grupo E têm ticket alto (R$ 242) — esses são os que mais doem se forem embora, prioridade máxima de reativação.

5 · Bônus que assustou. Fiz uma query extra: "quantos % dos meus clientes voltam a comprar?". Resposta:

métricavalor
Total de clientes93.358
Compraram só 1 vez90.557
Taxa de recorrência3,0%

97% das pessoas compram uma vez e somem. Isso muda completamente a estratégia: o problema do negócio NÃO é trazer mais gente (a aquisição já funciona) — é fazer a galera voltar. Esse insight, sozinho, justifica o projeto.

Resultado

A base segmentada

O que dá pra levar daqui

Em uma linha: o que esse projeto ensina

Que dados sem ação não valem nada. RFM é poderoso porque traduz números frios ("recência 180 dias, freq 2, valor R$ 300") em rótulos de negócio que qualquer pessoa entende e age em cima ("Em risco" → "campanha de reativação amanhã"). Ferramenta simples, impacto enorme.

Coisas técnicas que apareceram aqui: WITH (CTE) encadeadas, JOIN múltiplos, julianday() para calcular dias entre datas, NTILE(5) para criar quintis, CASE WHEN para regras de negócio, agregação após classificação.