Deletando registros duplicados no MySQL

Esta é uma tarefa que sempre alguem aparece em IRC/fórum precisando. Então deixarei registrado aqui para servir como uma referência.

Como podem ver abaixo, não será necessário usar qualquer linguagem de programação para realizar esta operação, apenas um client que mantenha uma sessão se for utilizar o método como tabela temporária.

mysql> INSERT INTO teste (nome) VALUES ('Felipe');
Query OK, 1 row affected (0.00 sec)
 
mysql> INSERT INTO teste (nome) VALUES ('Felipe');
Query OK, 1 row affected (0.00 sec)
 
mysql> INSERT INTO teste (nome) VALUES ('Felipe');
Query OK, 1 row affected (0.00 sec)
 
mysql> INSERT INTO teste (nome) VALUES ('Felipe');
Query OK, 1 row affected (0.00 sec)
 
mysql> SELECT * FROM teste;
+----+--------+
| id | nome   |
+----+--------+
| 10 | Felipe | 
|  9 | Felipe | 
|  6 | Felipe | 
|  4 | Pierre | 
|  5 | Diogo  | 
| 11 | Felipe | 
| 12 | Felipe | 
+----+--------+
7 rows IN SET (0.00 sec)
 
mysql> DELETE a FROM teste a, teste b WHERE a.nome = b.nome AND b.id IS NOT NULL AND a.id <> b.id;
Query OK, 4 rows affected (0.00 sec)
 
mysql> SELECT * FROM teste;
+----+--------+
| id | nome   |
+----+--------+
|  4 | Pierre | 
|  5 | Diogo  | 
| 12 | Felipe | 
+----+--------+
3 rows IN SET (0.00 sec)

E usando tabela temporária...

mysql> SELECT * FROM teste ORDER BY id;
+----+--------+
| id | nome   |
+----+--------+
|  4 | Pierre | 
|  5 | Diogo  | 
| 27 | Felipe | 
| 32 | Felipe | 
| 33 | Felipe | 
| 34 | Felipe | 
| 35 | Pierre | 
| 36 | Pierre | 
| 37 | Pierre | 
| 38 | Mateus | 
+----+--------+
10 rows IN SET (0.00 sec)
 
 
mysql> CREATE TEMPORARY TABLE fooooo AS SELECT * FROM teste GROUP BY nome HAVING count(*) > 1;
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0
 
mysql> SELECT * FROM fooooo;
+----+--------+
| id | nome   |
+----+--------+
| 34 | Felipe | 
| 37 | Pierre | 
+----+--------+
2 rows IN SET (0.00 sec)
 
mysql> DELETE FROM teste USING teste, fooooo WHERE teste.nome = fooooo.nome AND teste.id <> fooooo.id;
Query OK, 6 rows affected (0.00 sec)
 
mysql> SELECT * FROM teste ORDER BY id;
+----+--------+
| id | nome   |
+----+--------+
|  5 | Diogo  | 
| 34 | Felipe | 
| 37 | Pierre | 
| 38 | Mateus | 
+----+--------+
4 rows IN SET (0.00 sec)

Embora a sintaxe seja meio estranha, funciona!

Para aqueles que gostam de referências, para entender bem os detalhes (faz bem!): http://dev.mysql.com/doc/refman/5.0/en/delete.html - O que não é nem um pouco difícil de encontrar, hehe. :P

Isso caiu na minha

Isso caiu na minha entrevista de estágio. Só era um pouco diferente, mas envolvia registros duplicados tb. Bom saber isso! :D

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options