MySQL - Tratamento de duplicatas

Geralmente, as tabelas ou conjuntos de resultados às vezes contêm registros duplicados. Na maioria das vezes, é permitido, mas às vezes é necessário para impedir registros duplicados. É necessário identificar registros duplicados e removê-los da tabela. Este capítulo descreverá como evitar a ocorrência de registros duplicados em uma tabela e como remover os registros duplicados já existentes.

Evitando que ocorram duplicatas em uma tabela

Você pode usar um PRIMARY KEY ou um UNIQUE Índice em uma tabela com os campos apropriados para evitar registros duplicados.

Vejamos um exemplo - A tabela a seguir não contém esse índice ou chave primária, portanto, permitiria registros duplicados para first_name e last_name.

CREATE TABLE person_tbl (
   first_name CHAR(20),
   last_name CHAR(20),
   sex CHAR(10)
);

Para evitar que vários registros com os mesmos valores de nome e sobrenome sejam criados nesta tabela, adicione um PRIMARY KEYà sua definição. Ao fazer isso, também é necessário declarar que as colunas indexadas sãoNOT NULL, porque um PRIMARY KEY não permite NULL valores -

CREATE TABLE person_tbl (
   first_name CHAR(20) NOT NULL,
   last_name CHAR(20) NOT NULL,
   sex CHAR(10),
   PRIMARY KEY (last_name, first_name)
);

A presença de um índice exclusivo em uma tabela normalmente causa a ocorrência de um erro se você inserir um registro na tabela que duplica um registro existente na coluna ou colunas que definem o índice.

Use o INSERT IGNORE comando ao invés do INSERTcomando. Se um registro não duplica um registro existente, então o MySQL o insere normalmente. Se o registro for uma duplicata, oIGNORE palavra-chave diz ao MySQL para descartá-lo silenciosamente sem gerar um erro.

O exemplo a seguir não apresenta erros e, ao mesmo tempo, também não insere registros duplicados.

mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Jay', 'Thomas');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Jay', 'Thomas');
Query OK, 0 rows affected (0.00 sec)

Use o REPLACEcomando em vez do comando INSERT. Se o registro for novo, ele é inserido da mesma forma que com INSERT. Se for uma duplicata, o novo registro substituirá o antigo.

mysql> REPLACE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Ajay', 'Kumar');
Query OK, 1 row affected (0.00 sec)

mysql> REPLACE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Ajay', 'Kumar');
Query OK, 2 rows affected (0.00 sec)

Os comandos INSERT IGNORE e REPLACE devem ser escolhidos de acordo com o comportamento de tratamento de duplicatas que você deseja efetuar. O comando INSERT IGNORE mantém o primeiro conjunto de registros duplicados e descarta o restante. O comando REPLACE mantém o último conjunto de duplicatas e apaga as anteriores.

Outra maneira de impor exclusividade é adicionar um UNIQUE índice em vez de uma CHAVE PRIMÁRIA para uma tabela.

CREATE TABLE person_tbl (
   first_name CHAR(20) NOT NULL,
   last_name CHAR(20) NOT NULL,
   sex CHAR(10)
   UNIQUE (last_name, first_name)
);

Contando e Identificando Duplicados

A seguir está a consulta para contar registros duplicados com first_name e last_name em uma tabela.

mysql> SELECT COUNT(*) as repetitions, last_name, first_name
   -> FROM person_tbl
   -> GROUP BY last_name, first_name
   -> HAVING repetitions > 1;

Esta consulta retornará uma lista de todos os registros duplicados na tabela person_tbl. Em geral, para identificar conjuntos de valores que estão duplicados, siga as etapas fornecidas a seguir.

  • Determine quais colunas contêm os valores que podem ser duplicados.

  • Liste essas colunas na lista de seleção de coluna, junto com o COUNT(*).

  • Liste as colunas no GROUP BY cláusula também.

  • Adicione um HAVING cláusula que elimina os valores exclusivos exigindo que as contagens de grupo sejam maiores que um.

Eliminando duplicatas de um resultado de consulta

Você pode usar o DISTINCT junto com a instrução SELECT para descobrir os registros exclusivos disponíveis em uma tabela.

mysql> SELECT DISTINCT last_name, first_name
   -> FROM person_tbl
   -> ORDER BY last_name;

Uma alternativa ao comando DISTINCT é adicionar uma cláusula GROUP BY que nomeia as colunas que você está selecionando. Isso tem o efeito de remover duplicatas e selecionar apenas as combinações exclusivas de valores nas colunas especificadas.

mysql> SELECT last_name, first_name
   -> FROM person_tbl
   -> GROUP BY (last_name, first_name);

Removendo Duplicados Usando Substituição de Mesa

Se você tiver registros duplicados em uma tabela e quiser remover todos os registros duplicados dessa tabela, siga o procedimento abaixo.

mysql> CREATE TABLE tmp SELECT last_name, first_name, sex
   -> FROM person_tbl;
   -> GROUP BY (last_name, first_name);

mysql> DROP TABLE person_tbl;
mysql> ALTER TABLE tmp RENAME TO person_tbl;

Uma maneira fácil de remover registros duplicados de uma tabela é adicionar um INDEX ou uma PRIMARY KEY a essa tabela. Mesmo se esta tabela já estiver disponível, você pode usar esta técnica para remover os registros duplicados e você estará seguro no futuro também.

mysql> ALTER IGNORE TABLE person_tbl
   -> ADD PRIMARY KEY (last_name, first_name);