Ich muss DELETE
Zeilen für die angegebene Seite in einer MySQL
Tabelle duplizieren .
Wie kann ich das mit einer SQL-Abfrage machen?
DELETE (DUPLICATED TITLES) FROM table WHERE SID = "1"
So etwas, aber ich weiß nicht, wie ich es machen soll.
mysql
duplicates
Ali Demirci
quelle
quelle
Antworten:
Dadurch werden vorhandene Duplikate entfernt, ohne dass eine neue Tabelle erstellt werden muss
Hinweis: Funktioniert nur gut, wenn der Index in den Speicher passt
quelle
ALTER IGNORE
.ALTER TABLE foo ENGINE MyISAM
los, um es zu umgehen, und wechselte danach den Motor zurück.Angenommen, Sie haben eine Tabelle
employee
mit den folgenden Spalten:So löschen Sie die Zeilen mit einer doppelten
first_name
Spalte:quelle
employee
sich für eine Indexübereinstimmung gegen sich selbst anschließen, und eine>
Überprüfung eines Index wird für große Tabellen langsam sein. Wäre es nicht besser zuSELECT MAX(ID) FROM t GROUP BY unique
und dannJOIN
zu einer exakten Übereinstimmung vonID
zuMAX(ID)
?Entfernen Sie anschließend Duplikate für alle SIDs, nicht nur für einzelne.
Mit temporärer Tabelle
Da
temp_table
es frisch erstellt wurde, hat es keine Indizes. Sie müssen sie neu erstellen, nachdem Sie Duplikate entfernt haben. Sie können überprüfen, mit welchen Indizes Sie in der Tabelle sindSHOW INDEXES IN table
Ohne temporäre Tabelle:
quelle
SELECT * FROM table GROUP BY title, SID;
Es hängt alles davon ab, wie gut Sie wissen, was Sie tun.Löschen doppelter Zeilen in MySQL an Ort und Stelle (vorausgesetzt, Sie haben eine Zeitstempelspalte zum Sortieren) exemplarische Vorgehensweise:
Erstellen Sie die Tabelle und fügen Sie einige Zeilen ein:
Entfernen Sie die vorhandenen Duplikate:
Sie sind fertig, doppelte Zeilen werden entfernt, die letzte nach Zeitstempel bleibt erhalten.
Für diejenigen unter Ihnen ohne Zeitstempel oder eindeutige Spalte.
Sie haben keine
timestamp
oder eine eindeutige Indexspalte zum Sortieren? Du lebst in einem Zustand der Entartung. Sie müssen zusätzliche Schritte ausführen, um doppelte Zeilen zu löschen.Erstellen Sie die Pinguintabelle und fügen Sie einige Zeilen hinzu
Erstellen Sie einen Klon der ersten Tabelle und kopieren Sie ihn hinein.
Das maximale Aggregat arbeitet mit dem neuen Moo-Index:
beobachten und aufräumen
Was macht diese große SQL-Löschanweisung?
Tabellenpinguine mit dem Alias 'a' werden in einer Teilmenge von Tabellenpinguinen mit dem Namen 'b' zusammengefasst. Die rechte Tabelle 'b', die eine Teilmenge ist, findet den maximalen Zeitstempel (oder das maximale Moo), gruppiert nach den Spalten foo und bar. Dies ist auf die linke Tabelle 'a' abgestimmt. (foo, bar, baz) links hat jede Zeile in der Tabelle. Die rechte Teilmenge 'b' hat eine (Maxtimestamp, foo, bar), die nur auf diejenige abgestimmt ist, die die max.
Jede Zeile, die nicht das Maximum ist, hat den Wert maxtimestamp von NULL. Filtern Sie nach diesen NULL-Zeilen und Sie haben eine Reihe aller Zeilen, die nach foo und bar gruppiert sind und nicht die neueste Zeitstempel-Basis sind. Löschen Sie diese.
Erstellen Sie eine Sicherungskopie der Tabelle, bevor Sie diese ausführen.
Verhindern Sie, dass dieses Problem in dieser Tabelle jemals wieder auftritt:
Wenn Sie dies zum Laufen gebracht haben und Ihr "Duplicate Row" -Feuer gelöscht haben. Toll. Definieren Sie nun einen neuen zusammengesetzten eindeutigen Schlüssel in Ihrer Tabelle (in diesen beiden Spalten), um zu verhindern, dass überhaupt weitere Duplikate hinzugefügt werden.
Wie bei einem guten Immunsystem sollten die schlechten Reihen zum Zeitpunkt des Einfügens nicht einmal in die Tabelle zugelassen werden. Später senden alle Programme, die Duplikate hinzufügen, ihren Protest, und wenn Sie sie beheben, tritt dieses Problem nie wieder auf.
quelle
ID
Spalte für das automatische Inkrementieren enthält , muss dieON
Klausel nur mit derID
Spalte übereinstimmen , sonst nichts.Nachdem ich selbst auf dieses Problem in einer riesigen Datenbank gestoßen war, war ich von der Leistung der anderen Antworten nicht ganz beeindruckt. Ich möchte nur die letzte doppelte Zeile behalten und den Rest löschen.
In einer Anweisung mit einer Abfrage ohne temporäre Tabelle funktionierte dies am besten für mich.
Die einzige Einschränkung ist, dass ich die Abfrage mehrmals ausführen muss, aber trotzdem fand ich, dass sie für mich besser funktioniert als die anderen Optionen.
quelle
Das scheint bei mir immer zu funktionieren:
Dadurch wird die niedrigste ID für jeden der Dupes und den Rest der Nicht-Dupe-Datensätze beibehalten.
Ich habe auch Folgendes unternommen, damit das Dupe-Problem nach dem Entfernen nicht mehr auftritt:
Mit anderen Worten, ich erstelle ein Duplikat der ersten Tabelle, füge einen eindeutigen Index für die Felder hinzu, von denen ich keine Duplikate möchte, und mache dann einen,
Insert IGNORE
der den Vorteil hat, dass er nicht wie gewohnt fehlschlägtInsert
dass er beim ersten Versuch ausfällt ein doppelter Datensatz, der auf den beiden Feldern basiert und solche Datensätze eher ignoriert.Beim Verschieben wird es unmöglich, doppelte Datensätze basierend auf diesen beiden Feldern zu erstellen.
quelle
ORDER BY
in der brauchenSELECT
, um sicher zu sein, welche Platte es tatsächlich in die schafftNoDupeTable
?ORDER by ID Asc
konnte es nicht schaden, also werde ich meine Antwort trotzdem bearbeiten.Select Max(ID)
und dannOrder by Max(ID)
ausführen, aber alles, was Sie tun würden, ist die Reihenfolge der Einfügung umzukehren. Um die höchste ID zu erhalten, ist meines Erachtens ein komplexerer Select-Join erforderlich, da unabhängig davon, wie Sie oben bestellen, die Feldwerte von der niedrigeren ID abgerufen werden.MAX(ID)
oderMIN(ID)
und Spaltennamen anstatt*
in derSELECT FROM DupeTable
obwohl, sonst erhalten Sie nur einen derID
zufällig. Tatsächlich erfordern viele SQLs und sogar MySQL strict das Aufrufen einer Aggregatfunktion für jede Spalte, die nicht in derGROUP BY
Klausel angegeben ist.ID,First,Last,Notes
und Datensätzen hätte1,Bob,Smith,NULL
und2,Bob,Smith,Arrears
dann a ausführenSELECT *Max(ID), First,Last,Notes FROM DupeTable group by First,Last
würde, würden beide denselben Datensatz 1 zurückgeben, außer mit einer anderen ID. Max (ID) würde zurückkehren2,Bob,Smith,NULL
und Min (ID) würde zurückkehren1,Bob,Smith,NULL
. Um die zweite Platte mit "Arrears" in den Notizen zu erhalten, ist meiner Meinung nach ein Join erforderlich.Das Folgende funktioniert für alle Tabellen
quelle
Hier ist eine einfache Antwort:
quelle
and a.id_field = b.id
LEFT JOIN
to mussb
nur verglichen werdenb.id
=a.id_field
vorausgesetzt, esfield_id
handelt sich um eine eindeutige automatische Inkrement-ID. soa.field_being_repeated = b.field_being_repeated
ist irrelevant. (existiert auchb.id_field
nicht in dieser Abfrage, es istb.id
.Diese Arbeit für mich, um alte Aufzeichnungen zu entfernen:
Sie können min (e.id) durch max (e.id) ersetzen, um die neuesten Datensätze zu entfernen.
quelle
quelle
Ich finde Werners Lösung oben am bequemsten, da sie unabhängig vom Vorhandensein eines Primärschlüssels funktioniert, nicht mit Tabellen herumspielt, zukunftssicheres einfaches SQL verwendet und sehr verständlich ist.
Wie ich in meinem Kommentar festgestellt habe, wurde diese Lösung jedoch nicht richtig erklärt. Das ist also meins, basierend darauf.
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) Löschen Sie die hinzugefügte Spalte
Ich schlage vor, dass Sie die von Ihnen hinzugefügte Einschränkung beibehalten, damit neue Duplikate in Zukunft verhindert werden.
quelle
Bei diesem Verfahren werden alle Duplikate (einschließlich Vielfache) in einer Tabelle entfernt, wobei das letzte Duplikat beibehalten wird. Dies ist eine Erweiterung von Abrufs des letzten Datensatzes in jeder Gruppe
Hoffe das ist nützlich für jemanden.
quelle
Ein weiterer einfacher Weg ... mit UPDATE IGNORE:
Sie müssen einen Index für eine oder mehrere Spalten verwenden (Typindex). Erstellen Sie eine neue temporäre Referenzspalte (nicht Teil des Index). In dieser Spalte markieren Sie die Unikate, indem Sie sie mit der Ignorierklausel aktualisieren. Schritt für Schritt:
Fügen Sie eine temporäre Referenzspalte hinzu, um die Unikate zu markieren:
=> Dadurch wird Ihrer Tabelle eine Spalte hinzugefügt.
Aktualisieren Sie die Tabelle, versuchen Sie, alles als eindeutig zu markieren, ignorieren Sie jedoch mögliche Fehler aufgrund eines Problems mit doppelten Schlüsseln (Datensätze werden übersprungen):
=> Sie werden feststellen, dass Ihre doppelten Datensätze nicht als eindeutig markiert werden = 'Ja', dh nur einer von jedem Satz doppelter Datensätze wird als eindeutig markiert.
Löschen Sie alles, was nicht eindeutig ist:
=> Dadurch werden alle doppelten Datensätze entfernt.
Lass die Spalte fallen ...
quelle
unique
Spalte MUSS zusammen mit den aktuell duplizierten Spalten zu einer eindeutigen Einschränkung hinzugefügt werden, da sonst das Ganze nicht funktioniert, da SETunique
= 'Yes' niemals fehlschlagen würde.unique
Beachten Sie auch, dass dies ein MySQL-Schlüsselwort ist. Es müssen also die Backticks vorhanden sein (wie bereits richtig angezeigt). Die Verwendung eines anderen Wortes für die Spalte ist möglicherweise bequemer.Das Löschen von Duplikaten in MySQL-Tabellen ist ein häufiges Problem, das normalerweise mit bestimmten Anforderungen verbunden ist. Falls jemand interessiert ist, hier ( Entfernen Sie doppelte Zeilen in MySQL erkläre ich ), wie man eine temporäre Tabelle verwendet, um MySQL-Duplikate zuverlässig und schnell zu löschen, auch gültig für den Umgang mit großen Datenquellen (mit Beispielen für verschiedene Anwendungsfälle).
Ali , in deinem Fall kannst du so etwas ausführen:
quelle
quelle
Die Antwort von Love @ eric, aber es scheint nicht zu funktionieren, wenn Sie einen wirklich großen Tisch haben (ich bekomme,
The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay
wenn ich versuche, ihn zu betreiben). Daher habe ich die Join-Abfrage auf die doppelten Zeilen beschränkt und am Ende Folgendes erhalten:Die WHERE-Klausel in diesem Fall ermöglicht es MySQL, jede Zeile zu ignorieren, die kein Duplikat enthält, und wird auch ignoriert, wenn dies die erste Instanz des Duplikats ist, sodass nur nachfolgende Duplikate ignoriert werden. Wechseln Sie
MIN(baz)
zuMAX(baz)
, um die letzte Instanz anstelle der ersten beizubehalten.quelle
Dies funktioniert für große Tabellen:
So löschen Sie die älteste Änderung
max(id)
anmin(id)
quelle
Dadurch wird die Spalte
column_name
zu einem Primärschlüssel und in der Zwischenzeit werden alle Fehler ignoriert. Es werden also die Zeilen mit einem doppelten Wert für gelöschtcolumn_name
.quelle
Ich denke, dies funktioniert, indem die Tabelle im Grunde genommen kopiert und geleert wird und dann nur die unterschiedlichen Werte wieder in die Tabelle eingefügt werden. Bitte überprüfen Sie dies, bevor Sie große Datenmengen verarbeiten.
Erstellt eine Kopie Ihrer Tabelle
Leert Ihren Originaltisch
Kopiert alle unterschiedlichen Werte aus der kopierten Tabelle zurück in Ihre ursprüngliche Tabelle
Löscht Ihre temporäre Tabelle.
Sie müssen nach allen Feldern gruppieren, die Sie unterscheiden möchten.
quelle
quelle
So eliminiere ich normalerweise Duplikate
quelle
Sie können einfach eine DISTINCT-Klausel verwenden, um die "bereinigte" Liste auszuwählen (und hier ist ein sehr einfaches Beispiel dafür).
quelle
DISTINCT
Sie Sie verwenden, verlieren Sie alle Informationen über Duplikate, die Sie möglicherweise überhaupt hatten. Können Sie einen Weg zeigen, um Duplikate damit zu löschen?Könnte es funktionieren, wenn Sie sie zählen und dann Ihrer Löschabfrage ein Limit hinzufügen, so dass nur eines übrig bleibt?
Wenn Sie beispielsweise zwei oder mehr haben, schreiben Sie Ihre Abfrage wie folgt:
quelle
Es gibt nur ein paar grundlegende Schritte, um doppelte Daten aus Ihrer Tabelle zu entfernen:
Hier ist das vollständige Tutorial: https://blog.teamsql.io/deleting-duplicate-data-3541485b3473
quelle