Ich habe eine Tabelle mit folgenden Feldern:
id (Unique)
url (Unique)
title
company
site_id
Jetzt muss ich Zeilen mit demselben entfernen title, company and site_id
. Eine Möglichkeit besteht darin, das folgende SQL zusammen mit einem Skript ( PHP
) zu verwenden:
SELECT title, site_id, location, id, count( * )
FROM jobs
GROUP BY site_id, company, title, location
HAVING count( * ) >1
Nach dem Ausführen dieser Abfrage kann ich Duplikate mithilfe eines serverseitigen Skripts entfernen.
Ich möchte jedoch wissen, ob dies nur mit einer SQL-Abfrage möglich ist.
mysql
sql
duplicates
Chetan
quelle
quelle
Antworten:
Eine wirklich einfache Möglichkeit, dies zu tun, besteht darin, einen
UNIQUE
Index für die 3 Spalten hinzuzufügen . Geben Sie beim Schreiben derALTER
Anweisung dasIGNORE
Schlüsselwort an. Wie so:Dadurch werden alle doppelten Zeilen gelöscht. Als zusätzlichen Vorteil werden zukünftige
INSERTs
Duplikate fehlerhaft sein. Wie immer möchten Sie möglicherweise ein Backup erstellen, bevor Sie so etwas ausführen ...quelle
set session old_alter_table=1;
Wenn Sie die Spalteneigenschaften nicht ändern möchten, können Sie die folgende Abfrage verwenden.
Da Sie eine Spalte mit eindeutigen IDs haben (z. B.
auto_increment
Spalten), können Sie damit die Duplikate entfernen:In MySQL können Sie es mit dem NULL-sicheren Gleichheitsoperator (auch bekannt als "Raumschiffoperator" ) noch weiter vereinfachen :
quelle
MySQL hat Einschränkungen hinsichtlich des Verweises auf die Tabelle, aus der Sie löschen. Sie können dies mit einer temporären Tabelle umgehen, z. B.:
Aus Kostanos 'Vorschlag in den Kommentaren:
Die einzige langsame Abfrage oben ist LÖSCHEN für Fälle, in denen Sie eine sehr große Datenbank haben. Diese Abfrage könnte schneller sein:
quelle
DELETE FROM YourTable USING YourTable, tmpTable WHERE YourTable.id=tmpTable.id
DELETE
, sondern auchINSERT
zum temporären Tisch, es hat lange gedauert . Ein Index für die tmp-Tabelle könnte alsocreate index tmpTable_id_index on tmpTable (id)
zumindest für mich sehr hilfreich sein.create temporary table tmpTable (id int, PRIMARY KEY (id));
Wenn die
IGNORE
Anweisung nicht wie in meinem Fall funktioniert, können Sie die folgende Anweisung verwenden:quelle
Das Löschen von Duplikaten in MySQL-Tabellen ist ein häufiges Problem. Dies ist im Allgemeinen das Ergebnis einer fehlenden Einschränkung, um diese Duplikate vorab zu vermeiden. Dieses häufig auftretende Problem ist jedoch in der Regel mit spezifischen Anforderungen verbunden, die bestimmte Ansätze erfordern. Der Ansatz sollte unterschiedlich sein, abhängig beispielsweise von der Größe der Daten, dem doppelten Eintrag, der beibehalten werden soll (im Allgemeinen der erste oder der letzte), ob Indizes beibehalten werden müssen oder ob zusätzliche Änderungen vorgenommen werden sollen Aktion auf die duplizierten Daten.
Es gibt auch einige Besonderheiten in MySQL selbst, z. B., dass beim Ausführen eines Tabellen-UPDATE nicht auf dieselbe Tabelle in einer FROM-Ursache verwiesen werden kann (dies führt zu MySQL-Fehler Nr. 1093). Diese Einschränkung kann überwunden werden, indem eine innere Abfrage mit einer temporären Tabelle verwendet wird (wie bei einigen Ansätzen oben vorgeschlagen). Diese innere Abfrage funktioniert jedoch beim Umgang mit Big-Data-Quellen nicht besonders gut.
Es gibt jedoch einen besseren Ansatz zum Entfernen von Duplikaten, der sowohl effizient als auch zuverlässig ist und leicht an unterschiedliche Anforderungen angepasst werden kann.
Die allgemeine Idee besteht darin, eine neue temporäre Tabelle zu erstellen, in der Regel eine eindeutige Einschränkung hinzuzufügen, um weitere Duplikate zu vermeiden, und die Daten aus Ihrer früheren Tabelle in die neue einzufügen, während Sie sich um die Duplikate kümmern. Dieser Ansatz basiert auf einfachen MySQL INSERT-Abfragen, erstellt eine neue Einschränkung, um weitere Duplikate zu vermeiden, und überspringt die Verwendung einer inneren Abfrage zur Suche nach Duplikaten und einer temporären Tabelle, die im Speicher aufbewahrt werden sollte (wodurch auch große Datenquellen angepasst werden).
So kann es erreicht werden. Gegeben wir einen Tisch haben Mitarbeiter , mit den folgenden Spalten:
Um die Zeilen mit einer doppelten SSN- Spalte zu löschen und nur den ersten gefundenen Eintrag beizubehalten , kann der folgende Vorgang ausgeführt werden:
Technische Erklärung
⇒ Mit diesem Ansatz wurden 1,6 Millionen Register in weniger als 200 Sekunden in 6 KB konvertiert.
Chetan : Nach diesem Vorgang können Sie schnell und einfach alle Ihre Duplikate entfernen und eine EINZIGARTIGE Einschränkung erstellen, indem Sie Folgendes ausführen:
Natürlich kann dieser Prozess weiter modifiziert werden, um ihn beim Löschen von Duplikaten an unterschiedliche Anforderungen anzupassen. Es folgen einige Beispiele.
✔ Variation zum Beibehalten des letzten Eintrags anstelle des ersten
Manchmal müssen wir den letzten duplizierten Eintrag anstelle des ersten behalten.
✔ Variation zum Ausführen einiger Aufgaben für die Duplikate, z. B. Zählen der gefundenen Duplikate
Manchmal müssen wir die gefundenen duplizierten Einträge weiter verarbeiten (z. B. die Anzahl der duplizierten Einträge beibehalten).
✔ Variation zum Regenerieren der automatisch inkrementellen Feld-ID
Manchmal verwenden wir ein automatisch inkrementelles Feld. Um den Index so kompakt wie möglich zu halten, können wir das Löschen der Duplikate nutzen, um das automatisch inkrementelle Feld in der neuen temporären Tabelle neu zu generieren.
✔ Weitere Variationen
Abhängig vom gewünschten Verhalten sind auch viele weitere Modifikationen möglich. In den folgenden Abfragen wird beispielsweise eine zweite temporäre Tabelle verwendet, um neben 1) den letzten Eintrag anstelle des ersten zu behalten; und 2) einen Zähler für die gefundenen Duplikate erhöhen; auch 3) Generieren Sie die automatisch inkrementelle Feld-ID neu, während Sie die Eingabereihenfolge wie bei den vorherigen Daten beibehalten.
quelle
Es gibt noch eine andere Lösung:
quelle
Wenn Sie eine große Tabelle mit einer großen Anzahl von Datensätzen haben, funktionieren die oben genannten Lösungen nicht oder nehmen zu viel Zeit in Anspruch. Dann haben wir eine andere Lösung
quelle
Ich habe dieses Abfrage-Snipet für SQLServer, aber ich denke, es kann mit kleinen Änderungen in anderen DBMS verwendet werden:
Ich habe vergessen, Ihnen mitzuteilen, dass diese Abfrage die Zeile mit der niedrigsten ID der duplizierten Zeilen nicht entfernt. Wenn dies für Sie funktioniert, versuchen Sie diese Abfrage:
quelle
ERROR 1093: You can't specify target table 'Table' for update in FROM clause
"You can't specify target table 'Table' for update in FROM..."
Verwenden SieDELETE FROM Table WHERE Table.idTable IN ( SELECT MAX(idTable) FROM (SELECT * FROM idTable) AS tmp GROUP BY field1, field2, field3 HAVING COUNT(*) > 1)
:, um MySQL zu zwingen, eine temporäre Tabelle zu erstellen, um den Fehler zu beheben. In großen Datenmengen ist es jedoch sehr langsam. In solchen Fällen empfehle ich den Code von Andomar, der viel schneller ist.Der schnellere Weg besteht darin, bestimmte Zeilen in eine temporäre Tabelle einzufügen. Mit delete habe ich einige Stunden gebraucht, um Duplikate aus einer Tabelle mit 8 Millionen Zeilen zu entfernen. Mit Insert und Different dauerte es nur 13 Minuten.
quelle
TRUNCATE TABLE tableName
und 5. Zeile sollte sagenINSERT INTO tableName SELECT * FROM tempTableName;
Eine Lösung, die einfach zu verstehen ist und ohne Primärschlüssel funktioniert:
1) Fügen Sie eine neue boolesche Spalte hinzu
2) Fügen Sie eine Einschränkung für die duplizierten Spalten UND die neue Spalte hinzu
3) Setzen Sie die boolesche Spalte auf true. Dies ist aufgrund der neuen Einschränkung nur für eine der duplizierten Zeilen erfolgreich
4) Löschen Sie Zeilen, die nicht als tokeep markiert wurden
5) Lassen Sie die hinzugefügte Spalte fallen
Ich schlage vor, dass Sie die von Ihnen hinzugefügte Einschränkung beibehalten, damit neue Duplikate in Zukunft verhindert werden.
quelle
Löschen doppelter Zeilen mit der Anweisung DELETE JOIN MySQL stellt Ihnen die Anweisung DELETE JOIN zur Verfügung, mit der Sie doppelte Zeilen schnell entfernen können.
Die folgende Anweisung löscht doppelte Zeilen und behält die höchste ID bei:
quelle
Ich habe einen einfachen Weg gefunden. (auf dem neuesten Stand halten)
quelle
Einfach und schnell für alle Fälle:
quelle
Dadurch werden die doppelten Zeilen mit denselben Werten für Titel, Firma und Site gelöscht. Das erste Vorkommen wird beibehalten und alle Duplikate werden gelöscht
quelle
Ich besuche diese Seite immer dann, wenn ich "Duplikate aus MySQL entfernen" google, aber für meine theIGNORE-Lösungen funktioniert dies nicht, da ich eine InnoDB-MySQL-Tabelle habe
Dieser Code funktioniert jederzeit besser
tableToclean = Der Name der Tabelle, die Sie bereinigen müssen
tableToclean_temp = Eine temporäre Tabelle, die erstellt und gelöscht wurde
quelle
Diese Lösung verschiebt die Duplikate in eine Tabelle und die Unikate in eine andere .
quelle
SELECT * FROM jobs GROUP BY site_id, company, title, location
?Ab Version 8.0 (2018) unterstützt MySQL endlich Fensterfunktionen .
Fensterfunktionen sind sowohl praktisch als auch effizient. Hier ist eine Lösung, die zeigt, wie Sie diese Aufgabe lösen können.
In einer Unterabfrage können wir
ROW_NUMBER()
jedem Datensatz in der Tabelle innerhalb voncolumn1/column2
Gruppen eine Position zuweisen , geordnet nachid
. Wenn keine Duplikate vorhanden sind, erhält der Datensatz die Zeilennummer1
. Wenn ein Duplikat vorhanden ist, werden diese durch Aufsteigenid
(beginnend mit1
) nummeriert .Sobald die Datensätze in der Unterabfrage ordnungsgemäß nummeriert sind, löscht die äußere Abfrage nur alle Datensätze, deren Zeilennummer nicht 1 ist.
Abfrage:
quelle
So löschen Sie den doppelten Datensatz in einer Tabelle.
oder
quelle
quelle
Um Datensätze mit eindeutigen Spalten zu duplizieren, z. B. COL1, COL2, sollte COL3 nicht repliziert werden (Angenommen, wir haben 3 in der Tabellenstruktur eindeutige Spalten übersehen und mehrere doppelte Einträge in die Tabelle vorgenommen).
Hoffnung wird dev helfen.
quelle
TL; TR;
Ein ausführlich beschriebenes Tutorial zur Lösung dieses Problems finden Sie auf der Website mysqltutorial.org :
So löschen Sie doppelte Zeilen in MySQL
Es wird sehr deutlich gezeigt, wie doppelte Zeilen auf drei verschiedene Arten gelöscht werden :
A) Mit
DELETE JOIN
AussageB) Verwenden einer Zwischentabelle
C) Unter Verwendung
ROW_NUMBER()
FunktionIch hoffe, dass es jemandem helfen wird.
quelle
Ich habe eine Tabelle, die vergisst, einen Primärschlüssel in die ID-Zeile einzufügen. Allerdings hat die ID auto_increment. Aber eines Tages wird das MySQL-Bin-Protokoll in der Datenbank wiederholt, wobei einige doppelte Zeilen eingefügt werden.
Ich entferne die doppelte Zeile durch
select T1.* from table_name T1 inner join (select count(*) as c,id from table_name group by id) T2 on T1.id = T2.id where T2.c > 1 group by T1.id;
Löschen Sie die doppelten Zeilen nach ID
Fügen Sie die Zeile aus den exportierten Daten ein.
Fügen Sie dann den Primärschlüssel auf id hinzu
quelle
Ich möchte etwas genauer sagen, welche Datensätze ich lösche. Hier ist meine Lösung:
quelle
Sie können die doppelten Datensätze einfach aus diesem Code löschen.
quelle
Ich musste dies mit Textfeldern tun und stieß auf die Grenze von 100 Bytes im Index.
Ich habe dieses Problem gelöst, indem ich eine Spalte hinzugefügt, einen MD5-Hash der Felder erstellt und die Änderung vorgenommen habe.
quelle