Encontrando registros duplicados

Um colega meu veio me questionar como encontrar campos duplicados no oracle, segue um passo a passo de como posso encontrar estes registros.

Primeiramente fiz uma tabela de exemplo bem simples;

CREATE TABLE T1 
    (CODIGO NUMBER(11)
    ,CPF NUMBER(14)
    ,NOME VARCHAR2(200)
    ,DT_NASC DATE);

ALTER TABLE T1 
  ADD CONSTRAINT PK_T1 
  PRIMARY KEY (CODIGO);

ALTER TABLE T1 
  ADD CONSTRAINT 
  UK_CPF_T1 UNIQUE (CPF);

E após criar a tabela populei com alguns registros.
Mas aqui no meu caso eu criei uma Unique Key sobre o campo CPF, e como isso não ocorre em nenhum sistema, kkkk, esta chave foi desabilitada e alguns CPF´s foram duplicados.
E ao tentar habilitar a UK apareceu o seguinte erro:

SQL > ALTER TABLE T1 ENABLE CONSTRAINT UK_CPF_T1;

ORA-02299: - Cannot validate (USER.UK_CPF_T1) - duplicate keys found.

E agora como encontrar os campos duplicados ?
Em dois selects vamos obter os campos duplicados distintos.

Primeiro vamos encontrar os CPF´s que contem mais de 1 registro igual na base.

SQL > SELECT CPF,COUNT(1) FROM T1 GROUP BY CPF HAVING COUNT(1) > 1;

       CPF   COUNT(1)
---------- ----------
  10186329          2
  10190094          2

2 rows selected.

Encontramos 2 registros de CPF´s com mais de 1 registro igual. Agora vamos transforma-los em valores distintos.

SELECT ROWID,A.CPF,A.NOME FROM T1 A WHERE A.CPF IN 
(SELECT B.CPF FROM T1 B GROUP BY B.CPF HAVING COUNT(1) > 1)
ORDER BY 2;

ROWID                     CPF NOME
------------------ ---------- ---------------------------------------------------------------------------
AAACjoAAEAAAABiAAX   10186329 João da Silva Preira
AAACjoAAEAAAAJUABa   10186329 João da Silva Pereira
AAACjoAAEAAAAKWAAh   10190094 Margarida Marta Oliva Berggio
AAACjoAAEAAAAMSAAQ   10190094 Creuza de Souza

4 rows selected.

E agora estamos com os campos completos e já podemos passar para o analista do sistema ou responsavel pelos cadastros decidir quem irá ficar na base.

Aqui no exemplo fui informado que o cadastro [João da Silva Preira] deveria ser excluido, e o cadastro da Sra. Creuza de Souza estava errado e pelo sistema mesmo foi corrigido.

Então vamos excluir o registro [João da Silva Preira]

SQL> DELETE T1 WHERE ROWID = 'AAACjoAAEAAAABiAAX';

1 row deleted.
SQL> SELECT CPF,NOME FROM T1 WHERE CPF =10186329;

       CPF NOME
---------- ---------------------------------------------------------------------------
  10186329 João da Silva Pereira

Lembrando que ao tentar habilitar uma constraint podemos usar outro recurso que é a EXCEPTIONS conforme artigo do Bruno Erros de habilitação de constraints de Outubro 17, 2011.

%name Encontrando registros duplicados

Autor: Rafael Stoever

Bacharel em Sistema de Informação pela Uniasselvi, atualmente cursando Gerenciamento de Projetos em TI pela Pós Graduação Uniasselvi. Atuo como Analista de suporte a banco de dados – DBA pela Lumina Serviços em TI residente de Blumenau/ SC, OPN Certified Specialist, Certificado OCP 10g/11g/12c, OCE RAC10g e Linux 10g. Conhecimentos em Microsoft SqlSever, Mysql e programação web (php,asp).