Usunąć wszystkie zduplikowane wiersze z wyjątkiem jednego w MySQL? [duplikat]
Jak usunąć wszystkie duplikaty danych z tabeli MySQL?
Na przykład z następującymi danymi:
SELECT * FROM names;
+----+--------+
| id | name |
+----+--------+
| 1 | google |
| 2 | yahoo |
| 3 | msn |
| 4 | google |
| 5 | google |
| 6 | yahoo |
+----+--------+
Użyłbym SELECT DISTINCT name FROM names;
, gdyby to było SELECT
zapytanie.
Jak mam to zrobić z DELETE
aby usunąć tylko duplikaty i zachować tylko jeden zapis każdego z nich?
2 answers
Ostrzeżenie edytora: To rozwiązanie jest nieefektywne obliczeniowo i może obniżyć połączenie dla dużej tabeli.
UWAGA-Musisz zrobić to najpierw na kopii testowej Twojej tabeli!
Kiedy to zrobiłem, odkryłem, że o ile nie uwzględniłem również AND n1.id <> n2.id
, usunęło on każdy wiersz w tabeli.
-
Jeśli chcesz zachować wiersz z najniższą wartością
id
:DELETE n1 FROM names n1, names n2 WHERE n1.id > n2.id AND n1.name = n2.name
-
Jeśli chcesz zachować wiersz z najwyższą
id
wartością:DELETE n1 FROM names n1, names n2 WHERE n1.id < n2.id AND n1.name = n2.name
Użyłem tej metody w MySQL 5.1
Nie jestem pewien co do innych wersji.
Aktualizacja: ponieważ ludzie Googlujący do usuwania duplikatów kończą tutaj
Chociaż pytanie OP dotyczy DELETE
, należy pamiętać, że używanie INSERT
i DISTINCT
jest znacznie szybsze. W przypadku bazy danych z 8 milionami wierszy poniższe zapytanie zajęło 13 minut, podczas korzystania z DELETE
, zajęło to więcej niż 2 godziny, a jednak nie udało się ukończyć.
INSERT INTO tempTableName(cellId,attributeId,entityRowId,value)
SELECT DISTINCT cellId,attributeId,entityRowId,value
FROM tableName;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-15 21:09:35
Jeśli chcesz zachować wiersz z najniższą id
wartością:
DELETE FROM NAMES
WHERE id NOT IN (SELECT *
FROM (SELECT MIN(n.id)
FROM NAMES n
GROUP BY n.name) x)
Jeśli chcesz, aby wartość id
była najwyższa:
DELETE FROM NAMES
WHERE id NOT IN (SELECT *
FROM (SELECT MAX(n.id)
FROM NAMES n
GROUP BY n.name) x)
Subquery w subquery jest konieczne dla MySQL, lub dostaniesz błąd 1093.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-13 21:03:48