Duplicate possible:
Supprimer les lignes en double dans MySQL
Comment supprimer toutes les données en double d'une table MySQL?
Par exemple, avec les données suivantes:
SELECT * FROM names;
+----+--------+
| id | name |
+----+--------+
| 1 | google |
| 2 | yahoo |
| 3 | msn |
| 4 | google |
| 5 | google |
| 6 | yahoo |
+----+--------+
J'utiliserais SELECT DISTINCT name FROM names;
s'il s'agissait d'une requête SELECT
.
Comment ferais-je avec DELETE
pour ne supprimer que les doublons et ne garder qu'un enregistrement de chacun?
Avertissement de l'éditeur: Cette solution est inefficace du point de vue calcul et peut entraîner la perte de votre connexion pour une table volumineuse.
NB - Vous devez faire ceci en premier sur une copie test de votre table!
Lorsque je l'ai fait, j'ai constaté qu'à moins d'inclure également AND n1.id <> n2.id
, toutes les lignes de la table étaient supprimées.
Si vous souhaitez conserver la ligne avec la valeur id
la plus basse:
DELETE n1 FROM names n1, names n2 WHERE n1.id > n2.id AND n1.name = n2.name
Si vous voulez conserver la ligne avec la plus haute valeur id
name__:
DELETE n1 FROM names n1, names n2 WHERE n1.id < n2.id AND n1.name = n2.name
J'ai utilisé cette méthode dans MySQL 5.1
Pas sûr des autres versions.
Mise à jour: les personnes recherchant Google pour supprimer les doublons se retrouvent ici
Bien que la question du PO porte sur DELETE
name__, sachez que l'utilisation de INSERT
et de DISTINCT
est beaucoup plus rapide. Pour une base de données de 8 millions de lignes, la requête ci-dessous a pris 13 minutes. Si vous avez utilisé DELETE
name__, elle a pris plus de 2 heures et n'a pas encore abouti.
INSERT INTO tempTableName(cellId,attributeId,entityRowId,value)
SELECT DISTINCT cellId,attributeId,entityRowId,value
FROM tableName;
Si vous souhaitez conserver la ligne avec la valeur id
la plus basse:
DELETE FROM NAMES
WHERE id NOT IN (SELECT *
FROM (SELECT MIN(n.id)
FROM NAMES n
GROUP BY n.name) x)
Si vous voulez que la valeur id
soit la plus élevée:
DELETE FROM NAMES
WHERE id NOT IN (SELECT *
FROM (SELECT MAX(n.id)
FROM NAMES n
GROUP BY n.name) x)
La sous-requête d'une sous-requête est nécessaire pour MySQL, sinon vous obtiendrez une erreur 1093.