0Pricing
SQL Interview Prep · Aula

Eliminando duplicatas de linhas com segurança

Remova linhas exatamente duplicadas ou quase duplicadas, mantendo um registro canônico.

Eliminando duplicatas de linhas com segurança é uma aula grátis de SQL Interview Prep no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de SQL Interview Prep, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de SQL Interview Prep inclui 4 aulas no total.

O problema da deduplicação

"Esta tabela tem linhas duplicadas. Remova-as, mas mantenha uma cópia de cada uma." Quase toda entrevista de engenharia de dados inclui alguma variação disso. O desafio é fazer isso com segurança: manter exatamente uma linha canônica e não excluir acidentalmente registros distintos que apenas parecem semelhantes.

Abordaremos como detectar duplicatas, escolher qual cópia manter, fazer a deduplicação em um SELECT e excluir fisicamente duplicatas de uma tabela.

Defina primeiro o que é uma duplicata

A primeira pergunta a fazer ao entrevistador é: "O que faz duas linhas serem duplicatas?" As opções incluem:

  • Duplicatas exatas: todas as colunas são idênticas.
  • Duplicatas por chave: a mesma chave de negócio (por exemplo, o mesmo email), mas outras colunas podem ser diferentes.

A técnica varia em cada caso. Nunca presuma; esclarecer a definição de duplicata é a etapa mais importante, e os entrevistadores esperam que você faça essa pergunta.

Detectando duplicatas

Para encontrar chaves duplicadas, agrupe pelas colunas que definem uma duplicata e mantenha os grupos com uma contagem acima de um. Isso informa quais chaves são afetadas e quantas cópias existem antes de alterar qualquer coisa.

Executar primeiro uma consulta de detecção é uma boa prática que vale a pena mencionar: você verifica a dimensão do problema antes de excluir.

SELECT email, COUNT(*) AS copies
FROM users
GROUP BY email
HAVING COUNT(*) > 1
ORDER BY copies DESC;

Duplicatas exatas: DISTINCT

Se as duplicatas forem realmente idênticas em todas as colunas, uma visão deduplicada somente para leitura é tão simples quanto SELECT DISTINCT *. UNION (sem ALL) também remove linhas duplicadas.

Mas DISTINCT só ajuda quando você quer a linha inteira deduplicada e não precisa escolher qual cópia manter. Para duplicatas baseadas em chave, nas quais as colunas diferem, é necessário usar classificação.

-- Read-only dedup of exact-duplicate rows
SELECT DISTINCT customer_id, name, signup_date
FROM customers;

Duplicatas por chave: ROW_NUMBER

Quando as linhas compartilham uma chave, mas diferem em outras colunas, particione pela chave e numere cada cópia. rn = 1 marca a linha que será mantida; rn > 1 marca as excedentes a serem descartadas.

A ORDER BY dentro da janela determina qual cópia é canônica. Escolha isso deliberadamente; por exemplo, mantenha a linha atualizada mais recentemente.

SELECT *,
  ROW_NUMBER() OVER (
    PARTITION BY email
    ORDER BY updated_at DESC
  ) AS rn
FROM users;

Selecionando a cópia canônica

Envolva a numeração em uma CTE e mantenha apenas rn = 1. Isso retorna uma linha por chave, especificamente a linha que seu ORDER BY classificou em primeiro lugar.

Esta forma de SELECT é não destrutiva: é perfeita para criar uma visão limpa ou alimentar um INSERT ... SELECT em uma tabela de destino deduplicada sem tocar na origem.

WITH ranked AS (
  SELECT *,
    ROW_NUMBER() OVER (
      PARTITION BY email ORDER BY updated_at DESC
    ) AS rn
  FROM users
)
SELECT user_id, email, name, updated_at
FROM ranked
WHERE rn = 1;

A escolha da ordem é importante

A ORDER BY dentro da partição é uma decisão de negócio, não uma formalidade:

  • ORDER BY updated_at DESC mantém o registro mais recente.
  • ORDER BY created_at ASC mantém o registro original.
  • ORDER BY id ASC mantém a menor chave substituta, o que é útil como uma escolha arbitrária estável.

Adicione um critério de desempate único para que a linha escolhida seja determinística quando a coluna de ordenação principal também tiver empate.

ROW_NUMBER() OVER (
  PARTITION BY email
  ORDER BY updated_at DESC, id ASC
) AS rn

Excluindo fisicamente duplicatas

Para realmente remover duplicatas da tabela, identifique as linhas excedentes (rn > 1) e exclua-as. No PostgreSQL e no SQL Server, você pode excluir usando uma CTE; no MySQL, uma autojunção ou subconsulta é comum.

Sempre execute primeiro o SELECT correspondente para visualizar exatamente quais linhas desaparecerão. Excluir às cegas é como os candidatos erram essa pergunta.

WITH ranked AS (
  SELECT ctid,
    ROW_NUMBER() OVER (
      PARTITION BY email ORDER BY updated_at DESC, id ASC
    ) AS rn
  FROM users
)
DELETE FROM users
WHERE ctid IN (SELECT ctid FROM ranked WHERE rn > 1);

Padrão de exclusão com autojunção

Uma abordagem clássica e portável mantém a linha com o menor id por chave duplicada e exclui o restante usando uma autojunção. Ela não precisa de funções de janela, o que é importante em mecanismos mais antigos.

A condição de junção associa cada linha a outra linha que compartilha a mesma chave, mas tem um identificador menor; qualquer linha que tenha um correspondente com identificador menor é uma duplicata a ser excluída.

DELETE u1
FROM users u1
JOIN users u2
  ON u1.email = u2.email
 AND u1.id > u2.id;

Lista de verificação de segurança

Antes de excluir, proteja-se:

  • Envolva a exclusão em uma transação para poder usar ROLLBACK se a contagem parecer incorreta.
  • Execute primeiro SELECT COUNT(*) das linhas a excluir e faça uma verificação de razoabilidade.
  • Considere uma tabela de cópia de segurança: CREATE TABLE users_bak AS SELECT * FROM users.
  • Confirme se as colunas de PARTITION BY realmente definem uma duplicata, ou você poderá excluir registros distintos.
BEGIN;
-- run the DELETE, inspect row count
-- COMMIT; if correct, otherwise ROLLBACK;

Quase duplicatas e normalização

Às vezes, as linhas não são exatamente iguais, mas são logicamente iguais: 'Ann@X.com' e 'ann@x.com', por exemplo, ou ainda por causa de espaços no final. Particione com base em uma expressão normalizada, em vez da coluna bruta.

Mencionar a normalização demonstra maturidade: duplicatas do mundo real muitas vezes se ocultam por trás de diferenças entre maiúsculas e minúsculas, espaços em branco ou formatação que uma comparação ingênua de chaves não detecta.

ROW_NUMBER() OVER (
  PARTITION BY LOWER(TRIM(email))
  ORDER BY updated_at DESC, id ASC
) AS rn

Verificação rápida

Escolha a abordagem segura para a deduplicação.

Resumo: deduplicação segura

Faça a deduplicação de forma metódica:

  • Primeiro defina o que é uma duplicata e depois detecte usando GROUP BY / HAVING COUNT(*) > 1.
  • Duplicatas exatas → DISTINCT. Duplicatas por chave → ROW_NUMBER particionado pela chave; mantenha rn = 1.
  • A ORDER BY da janela escolhe a cópia canônica; adicione um critério de desempate único.
  • Exclua as linhas rn > 1 dentro de uma transação, depois de verificar a contagem.
  • Normalize as chaves para detectar quase duplicatas.

Perguntas Frequentes

A aula “Eliminando duplicatas de linhas com segurança” é grátis?

Sim — o texto completo de “Eliminando duplicatas de linhas com segurança” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de SQL Interview Prep, atualize para CoddyKit PRO. O curso de SQL Interview Prep inclui 4 aulas no total.

O que vou aprender em “Eliminando duplicatas de linhas com segurança”?

Remova linhas exatamente duplicadas ou quase duplicadas, mantendo um registro canônico. Você pratica SQL Interview Prep com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar SQL Interview Prep?

Nenhuma experiência prévia é necessária. SQL Interview Prep no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Eliminando duplicatas de linhas com segurança”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de SQL Interview Prep?

Sim. Cada aula de SQL Interview Prep inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Linhas Top-N por grupo com ROW_NUMBER
  2. Lidando com empates em Top-N
  3. Eliminando duplicatas de linhas com segurança
  4. Mantendo a linha mais recente por chave
← Voltar para SQL Interview Prep