---
title: "Diffs mensais do CNPJ: como transformar snapshots da Receita em sinais de prospecção"
description: "Sinais extraídos da comparação mensal do cadastro do CNPJ (filiais, CNAE, endereço, sócios) e como calculá-los em SQL sem falsos positivos."
url: "https://cnpjpedia.com.br/blog/diffs-mensais-cnpj-sinais-prospeccao"
date: "2026-10-23"
updated: "2026-10-23"
tags: ["Engenharia de dados", "ClickHouse", "Prospecção B2B", "CNPJ"]
reading_time_minutes: 8
author: "CNPJpedia"
language: "pt-BR"
---

# Diffs mensais do CNPJ: como transformar snapshots da Receita em sinais de prospecção

> Sinais extraídos da comparação mensal do cadastro do CNPJ (filiais, CNAE, endereço, sócios) e como calculá-los em SQL sem falsos positivos.

Publicado em 23 de outubro de 2026 · 8 min de leitura · Tags: Engenharia de dados, ClickHouse, Prospecção B2B, CNPJ

O cadastro do CNPJ que a Receita publica todo mês é uma fotografia: mostra como cada empresa está, não o que mudou. Mas quem guarda as fotografias e as compara ganha algo que o arquivo sozinho não oferece: **eventos**. Uma filial aberta, uma troca de atividade principal, uma mudança de cidade ou a entrada de um novo sócio são acontecimentos que, muitas vezes, vêm acompanhados de novas necessidades, e portanto de novas compras.

Este artigo apresenta um catálogo de sinais que dá para extrair da comparação mensal, a leitura comercial de cada um e uma implementação em SQL (ClickHouse) que evita os falsos positivos mais comuns.

## Por que diffs, e não só filtros

Um filtro responde "quais empresas são assim?". Um diff responde "quais empresas **ficaram** assim agora?". Para prospecção, a segunda pergunta costuma valer mais:

- o momento da mudança é quando a empresa está revendo fornecedores, sistemas e processos;
- uma lista de eventos recentes é pequena, específica e fácil de trabalhar com abordagem personalizada;
- o próprio evento é um bom motivo de contato ("vi que vocês abriram uma unidade em Campinas").

O custo é de engenharia: guardar os snapshots, normalizar os campos e calcular as diferenças com cuidado. Lembre também que o ritmo é mensal. O dump de outubro de 2026, por exemplo, foi publicado em 13 de outubro, então um evento que aconteceu no começo de setembro pode só aparecer agora.

## O catálogo de sinais

| Sinal | Como detectar | Leitura comercial | Ruído típico |
|---|---|---|---|
| **Nova empresa** | Raiz que não existia no mês anterior | Demanda por tudo: contabilidade, banco, software, equipamentos | Empresas de fachada, MEIs (se não forem o seu público) |
| **Nova filial** | Novo CNPJ com raiz já existente | Expansão: TI, telecom, mobiliário, segurança, recrutamento | Filiais abertas e baixadas em sequência |
| **Mudança de CNAE principal** | Valor diferente entre os meses | Mudança de modelo de negócio, novos produtos ou serviços | Correções cadastrais sem mudança real |
| **Novo CNAE secundário** | Código presente agora e ausente antes | Diversificação, nova linha de receita | Inclusões "por garantia" |
| **Mudança de município** | Município diferente | Mudança de sede: novos fornecedores locais | Recodificação de tabelas, ajustes de CEP |
| **Mudança de endereço na mesma cidade** | CEP ou logradouro diferente | Mudança para espaço maior ou menor | Variações de grafia ("R." e "RUA") |
| **Saída do Simples Nacional** | Data de exclusão preenchida | Crescimento acima do teto, ou pendência fiscal | Exclusões por débito (sinal de risco) |
| **Entrada ou saída de sócio** | Linha de sócio nova ou removida | Sucessão, investimento, nova gestão | Ajustes de qualificação |
| **Mudança de natureza jurídica** | Ltda que vira S.A., por exemplo | Preparação para investimento ou governança | Raro, mas relevante |
| **Mudança de situação** | Ativa para inapta, suspensa ou baixada | Risco: limpar da base, rever crédito | Reativações após regularização |

Nenhum desses sinais é uma intenção de compra declarada. São **gatilhos para olhar** a empresa com mais atenção, e funcionam melhor combinados com o ICP: uma nova filial de uma empresa fora do seu perfil continua fora do perfil.

## A base: snapshots versionados

O primeiro requisito é nunca sobrescrever o mês anterior. Uma tabela única, particionada por mês de referência, resolve isso de forma simples:

```sql
CREATE TABLE estab_snapshot
(
    referencia         Date,
    cnpj               FixedString(14),
    cnpj_basico        FixedString(8),
    situacao           LowCardinality(String),
    cnae_principal     LowCardinality(String),
    cnaes_secundarios  Array(LowCardinality(String)),
    uf                 LowCardinality(String),
    municipio          LowCardinality(String),
    cep                String,
    logradouro         String,
    numero             String,
    impressao          UInt64 MATERIALIZED cityHash64(
        situacao, cnae_principal, arraySort(cnaes_secundarios),
        uf, municipio, cep, upper(trim(logradouro)), upper(trim(numero)))
)
ENGINE = MergeTree
PARTITION BY referencia
ORDER BY (cnpj, referencia);
```

Dois detalhes fazem diferença:

- **Particionar por mês** permite descartar meses antigos com `DROP PARTITION` e comparar dois meses lendo só as partições necessárias.
- A coluna **`impressao`** é um hash dos campos monitorados, calculado na inserção. Comparar um inteiro por linha é muito mais barato do que comparar dez colunas, e só as linhas com hash diferente seguem para a análise campo a campo.

## Normalize antes de comparar

A maior fonte de falsos positivos não é a Receita mudar dados, e sim a mesma informação aparecer escrita de outro jeito. Por isso o hash acima já aplica:

- `upper(trim(...))` nos campos de texto livre, para ignorar maiúsculas e espaços;
- `arraySort(...)` na lista de CNAEs secundários, para que a ordem não gere diferença.

Outras normalizações úteis, conforme o campo:

- expandir abreviações de logradouro ("R" para "RUA", "AV" para "AVENIDA");
- tratar `S/N`, `SN` e vazio como o mesmo número;
- remover pontuação do CEP;
- mapear códigos antigos quando uma tabela de domínio for recodificada.

## Novas empresas e novas filiais

Com os snapshots no lugar, novos estabelecimentos são os CNPJs do mês atual que não existiam no anterior. A raiz diz se é uma empresa nova ou uma filial de uma empresa existente:

```sql
SELECT
    n.cnpj,
    n.uf,
    n.cnae_principal,
    if(n.cnpj_basico IN (SELECT cnpj_basico FROM estab_snapshot WHERE referencia = '2026-09-01'),
       'nova_filial', 'nova_empresa') AS tipo
FROM (SELECT * FROM estab_snapshot WHERE referencia = '2026-10-01') AS n
LEFT ANTI JOIN (SELECT cnpj FROM estab_snapshot WHERE referencia = '2026-09-01') AS a
    ON a.cnpj = n.cnpj;
```

O `LEFT ANTI JOIN` devolve apenas as linhas da esquerda sem correspondência na direita, sem precisar de `NOT IN` sobre dezenas de milhões de valores.

## Mudanças campo a campo

Para as linhas que existem nos dois meses e cujo hash mudou, transformamos cada campo monitorado numa tupla `(campo, antes, depois)` e mantemos só as que diferem:

```sql
SELECT cnpj, m.1 AS campo, m.2 AS antes, m.3 AS depois
FROM
(
    SELECT
        n.cnpj AS cnpj,
        [
            ('situacao',          a.situacao,       n.situacao),
            ('cnae_principal',    a.cnae_principal, n.cnae_principal),
            ('municipio',         a.municipio,      n.municipio),
            ('cnaes_secundarios', arrayStringConcat(arraySort(a.cnaes_secundarios), ','),
                                  arrayStringConcat(arraySort(n.cnaes_secundarios), ','))
        ] AS mudancas
    FROM (SELECT *, impressao FROM estab_snapshot WHERE referencia = '2026-10-01') AS n
    INNER JOIN (SELECT *, impressao FROM estab_snapshot WHERE referencia = '2026-09-01') AS a
        ON a.cnpj = n.cnpj
    WHERE a.impressao != n.impressao
)
ARRAY JOIN mudancas AS m
WHERE m.2 != m.3
ORDER BY cnpj, campo;
```

Repare no `SELECT *, impressao`: colunas `MATERIALIZED` não entram no `*` e precisam ser pedidas explicitamente.

O resultado é uma tabela de eventos com uma linha por mudança, pronta para gravar numa tabela `eventos` com a data de referência. O mesmo padrão vale para a tabela de empresas (capital social, natureza jurídica, porte), para o Simples (datas de exclusão) e para os sócios, comparando a chave composta de raiz, nome, documento mascarado e qualificação.

## Um freio de segurança antes de publicar

Às vezes o arquivo de origem muda de layout, uma tabela de domínio é recodificada ou uma parte do dump chega incompleta. Se o pipeline publicar alertas nessas condições, os usuários recebem milhares de "mudanças" falsas de uma vez. Uma checagem simples evita isso:

```sql
SELECT
    countIf(a.impressao != n.impressao)        AS alterados,
    count()                                     AS comparados,
    round(alterados / comparados * 100, 2)      AS pct_alterados
FROM (SELECT cnpj, impressao FROM estab_snapshot WHERE referencia = '2026-10-01') AS n
INNER JOIN (SELECT cnpj, impressao FROM estab_snapshot WHERE referencia = '2026-09-01') AS a
    ON a.cnpj = n.cnpj;
```

Guarde esse percentual a cada carga. Se ele ficar muito acima do histórico, segure a publicação dos eventos e investigue. A mesma lógica vale para o número de novos estabelecimentos e de mudanças por campo.

## Do evento à ação

Uma tabela de eventos só gera valor quando chega a quem vende. Algumas formas de entrega, da mais simples à mais integrada:

1. **Relatório mensal por segmento**: novas filiais e mudanças de CNAE dentro do ICP, numa planilha.
2. **Alertas por lista monitorada**: o vendedor acompanha suas contas e recebe um e-mail quando algo muda.
3. **Webhooks e integração com CRM**: o evento cria uma tarefa ou atualiza um campo no CRM, com o motivo do contato.
4. **Pontuação dinâmica**: eventos recentes aumentam a prioridade da conta por algumas semanas.

Em todos os casos, mostre o evento com contexto: o que mudou, de quanto para quanto e em qual mês de referência. "Mudou de São Paulo para Campinas no cadastro de outubro" é acionável; "houve uma alteração" não é.

## Cuidados finais

- **Eventos não são intenção.** Use-os para priorizar e personalizar, não para disparar mensagens automáticas em massa.
- **Sócios são pessoas.** Entrada e saída de sócio pessoa física envolve dado pessoal; trate com os cuidados da LGPD e evite expor nomes onde não for necessário.
- **Defasagem.** Deixe claro que o evento foi detectado no cadastro de um mês específico, não na data em que aconteceu.

## Conclusão

Guardar os snapshots mensais, normalizar antes de comparar, calcular um hash por linha e analisar campo a campo só o que mudou transforma um arquivo estático em um fluxo de sinais. Com um freio de segurança antes da publicação e uma entrega que chegue ao CRM, esses eventos viram motivos concretos de conversa com as empresas certas, no momento certo.

Para acompanhar mudanças em empresas monitoradas sem manter esse pipeline, [experimente o monitoramento da CNPJpedia](https://cnpjpedia.com.br/cadastro).

## Leia também

- [ClickHouse para busca de empresas: como modelar dezenas de milhões de CNPJs](https://cnpjpedia.com.br/blog/clickhouse-busca-empresas-modelagem.md): Como modelar o cadastro de CNPJ no ClickHouse: chave de ordenação, tipos, índices de salto, paginação por cursor e carga mensal sem downtime.
- [Como definir o ICP B2B com dados públicos: CNAE, porte e região na prática](https://cnpjpedia.com.br/blog/icp-b2b-cnae-porte-regiao.md): Como transformar seus melhores clientes em um ICP mensurável com CNAE, porte, região e idade da empresa, com pontuação, níveis A/B/C e erros comuns.
- [Processando o dump do CNPJ com Polars: do ZIP ao Parquet](https://cnpjpedia.com.br/blog/dump-cnpj-polars-zip-parquet.md): Tutorial para carregar o dump do CNPJ com Polars: conversão de latin-1, leitura lazy, tipagem, Parquet e consultas em streaming sem estourar a memória.
