Was ist der beste Weg, um doppelte Zeilen aus einer ziemlich großen SQL Server
Tabelle (dh mehr als 300.000 Zeilen) zu entfernen ?
Die Zeilen sind natürlich keine perfekten Duplikate, da das RowID
Identitätsfeld vorhanden ist.
Mein Tisch
RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null
sql-server
tsql
duplicates
Seibar
quelle
quelle
DELETE FROM
CTE-Begriff direkt verwenden können. Siehe stackoverflow.com/q/18439054/398670ROWID()
Funktion einfach durch die RowID-Spalte, falls vorhanden)Antworten:
Unter der Annahme, dass keine Nullen vorhanden sind, müssen Sie
GROUP BY
die eindeutigen Spalten undSELECT
dieMIN (or MAX)
RowId als Zeile beibehalten. Löschen Sie dann einfach alles, was keine Zeilen-ID hatte:Wenn Sie eine GUID anstelle einer Ganzzahl haben, können Sie diese ersetzen
mit
quelle
DELETE FROM MyTable WHERE RowId NOT IN (SELECT MIN(RowId) FROM MyTable GROUP BY Col1, Col2, Col3);
LEFT JOIN
ist weniger effizient alsNOT EXISTS
sqlinthewild.co.za/index.php/2010/03/23/... Die gleiche Website vergleicht auchNOT IN
vsNOT EXISTS
. sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in Von den 3 ist meiner Meinung nachNOT EXISTS
die beste Leistung. Alle drei generieren einen Plan mit einem Self-Join, der jedoch vermieden werden kann.DELETE MyTable FROM MyTable
Syntax korrekt? Ich sehe nicht , die Tabellennamen direkt nach der UmsetzungDELETE
als Option in der Dokumentation hier . Entschuldigung, wenn dies für andere offensichtlich ist. Ich bin ein Neuling in SQL und versuche nur zu lernen. Wichtiger als warum funktioniert es: Was ist der Unterschied zwischen dem Einfügen des Namens der Tabelle dort oder nicht?Ein anderer möglicher Weg, dies zu tun, ist
ich benutze
ORDER BY (SELECT 0)
oben, da es beliebig ist, welche Zeile im Falle eines Unentschieden beibehalten werden soll.Um die neueste zu erhalten, können
RowID
Sie sie beispielsweise verwendenORDER BY RowID DESC
Ausführungspläne
Der Ausführungsplan hierfür ist häufig einfacher und effizienter als der in der akzeptierten Antwort, da keine Selbstverbindung erforderlich ist.
Dies ist jedoch nicht immer der Fall. Ein Ort, an dem die
GROUP BY
Lösung bevorzugt werden könnte, sind Situationen, in denen ein Hash-Aggregat einem Stream-Aggregat vorgezogen wird .Die
ROW_NUMBER
Lösung wird immer fast den gleichen Plan geben, während dieGROUP BY
Strategie flexibler ist.Faktoren, die den Hash-Aggregat-Ansatz begünstigen könnten, wären
In extremen Versionen dieses zweiten Falls (wenn es nur sehr wenige Gruppen mit jeweils vielen Duplikaten gibt) könnte man auch in Betracht ziehen, einfach die Zeilen einzufügen, um sie in einer neuen Tabelle zu behalten, dann
TRUNCATE
das Original zu kopieren und sie zurück zu kopieren, um die Protokollierung im Vergleich zum Löschen von a zu minimieren sehr hoher Anteil der Reihen.quelle
uniqueidentifier
. Dieser ist viel einfacher und funktioniert perfekt auf jedem Tisch. Danke Martin.RowId
) zum Vergleichen gab.Es gibt einen guten Artikel zum Entfernen von Duplikaten auf der Microsoft Support-Website. Es ist ziemlich konservativ - Sie müssen alles in separaten Schritten erledigen - aber es sollte gut gegen große Tische funktionieren.
Ich habe in der Vergangenheit Self-Joins verwendet, um dies zu tun, obwohl es wahrscheinlich mit einer HAVING-Klausel verschönert werden könnte:
quelle
Die folgende Abfrage ist nützlich, um doppelte Zeilen zu löschen. Die Tabelle in diesem Beispiel
ID
als Identitätsspalte und die Spalten , die doppelten Daten sindColumn1
,Column2
undColumn3
.Die folgende Skript zeigt Verwendung von
GROUP BY
,HAVING
,ORDER BY
in einer Abfrage, und gibt die Ergebnisse mit doppelter Spalte und seiner Zählung.quelle
NOT IN
oft besser alsOUTER JOIN ... NULL
. Ich würde ein hinzufügen ,HAVING MAX(ID) IS NOT NULL
um die Abfrage obwohl obwohl semantisch es nicht notwendig sein sollte wie den Plan zu verbessern Beispiel , dass hierPostgres:
quelle
quelle
Dadurch werden doppelte Zeilen mit Ausnahme der ersten Zeile gelöscht
Siehe ( http://www.codeproject.com/Articles/157977/Remove-Duplicate-Rows-from-a-Table-in-SQL-Server )
quelle
Ich würde CTE bevorzugen, um doppelte Zeilen aus der SQL Server-Tabelle zu löschen
Es wird dringend empfohlen, diesem Artikel zu folgen: http://codaffection.com/sql-server-article/delete-duplicate-rows-in-sql-server/
quelle
So rufen Sie doppelte Zeilen ab:
So löschen Sie die doppelten Zeilen:
quelle
DELETE FROM
und zweitens nicht funktioniert, da Sie nichtSELECT
aus derselben Tabelle stammen können, aus der Sie stammenDELETE
. In MySQL sprengt diesMySQL error 1093
.Schnell und fehlerhaft, um exakte doppelte Zeilen zu löschen (für kleine Tabellen):
quelle
Ich bevorzuge die Unterabfrage \ mit count (*)> 1-Lösung gegenüber der inneren Verknüpfung, da ich sie leichter lesen konnte und es sehr einfach war, sie in eine SELECT-Anweisung umzuwandeln, um zu überprüfen, was gelöscht werden würde, bevor Sie sie ausführen.
quelle
MAX(id)
, um die letzteren Duplikate zu entfernen, undLIMIT 1000000
der inneren Abfrage hinzugefügt , damit nicht die gesamte Tabelle gescannt werden muss. Dies zeigte Fortschritte viel schneller als die anderen Antworten, die stundenlang zu hängen scheinen. Nachdem die Tabelle auf eine überschaubare Größe beschnitten wurde, können Sie mit den anderen Abfragen fertig werden. Tipp: Stellen Sie sicher, dass col1 / col2 / col3 Indizes für die Gruppierung nach enthält.quelle
Ich dachte, ich würde meine Lösung teilen, da sie unter besonderen Umständen funktioniert. In meinem Fall hatte die Tabelle mit doppelten Werten keinen Fremdschlüssel (da die Werte von einer anderen Datenbank dupliziert wurden).
PS: Wenn ich an solchen Dingen arbeite, verwende ich immer eine Transaktion. Dadurch wird nicht nur sichergestellt, dass alles als Ganzes ausgeführt wird, sondern ich kann auch testen, ohne etwas zu riskieren. Aber natürlich sollten Sie trotzdem ein Backup erstellen, nur um sicherzugehen ...
quelle
Diese Abfrage zeigte eine sehr gute Leistung für mich:
Es löschte 1 Million Zeilen in etwas mehr als 30 Sekunden aus einer Tabelle mit 2 Millionen (50% Duplikate).
quelle
CTE verwenden. Die Idee ist, eine oder mehrere Spalten zu verbinden, die einen doppelten Datensatz bilden, und dann zu entfernen, was immer Sie möchten:
quelle
Eine weitere einfache Lösung finden Sie unter dem hier eingefügten Link . Dieser ist leicht zu verstehen und scheint für die meisten ähnlichen Probleme effektiv zu sein. Es ist zwar für SQL Server, aber das verwendete Konzept ist mehr als akzeptabel.
Hier sind die relevanten Teile der verlinkten Seite:
Betrachten Sie diese Daten:
Wie können wir diese doppelten Daten löschen?
Fügen Sie zunächst eine Identitätsspalte in diese Tabelle ein, indem Sie den folgenden Code verwenden:
Verwenden Sie den folgenden Code, um das Problem zu beheben:
quelle
ROW_NUMBER
Version funktioniert in diesem Fall einwandfrei , ohne dass Sie vor Beginn eine neue Spalte hinzufügen müssen.Hier ist ein weiterer guter Artikel zum Entfernen von Duplikaten .
Es wird erläutert, warum es schwierig ist: " SQL basiert auf relationaler Algebra, und Duplikate können in der relationalen Algebra nicht auftreten, da Duplikate in einer Menge nicht zulässig sind. "
Die temporäre Tabellenlösung und zwei MySQL-Beispiele.
In Zukunft werden Sie dies auf Datenbankebene oder aus Anwendungssicht verhindern. Ich würde die Datenbankebene vorschlagen, da Ihre Datenbank für die Aufrechterhaltung der referenziellen Integrität verantwortlich sein sollte. Entwickler werden nur Probleme verursachen;)
quelle
Oh sicher. Verwenden Sie eine temporäre Tabelle. Wenn Sie eine einzelne, nicht sehr performante Aussage wünschen, die "funktioniert", können Sie folgendermaßen vorgehen:
Grundsätzlich findet die Unterauswahl für jede Zeile in der Tabelle die oberste Zeilen-ID aller Zeilen, die genau der betrachteten Zeile entsprechen. Am Ende erhalten Sie eine Liste von RowIDs, die die "ursprünglichen" nicht duplizierten Zeilen darstellen.
quelle
Ich hatte eine Tabelle, in der ich nicht doppelte Zeilen beibehalten musste. Ich bin mir nicht sicher über die Geschwindigkeit oder Effizienz.
quelle
HAVING COUNT(*) > 1
?Benutze das
quelle
Die andere Möglichkeit besteht darin, eine neue Tabelle mit denselben Feldern und mit einem eindeutigen Index zu erstellen . Dann bewegen sich alle Daten aus altem Tisch zu neuer Tabelle . Automatisch ignorieren SQL SERVER (es gibt auch eine Option, was zu tun ist, wenn ein doppelter Wert vorliegt: ignorieren, unterbrechen oder etw) doppelte Werte. Wir haben also dieselbe Tabelle ohne doppelte Zeilen. Wenn Sie keinen eindeutigen Index möchten, können Sie ihn nach den Übertragungsdaten löschen .
Insbesondere für größere Tabellen können Sie DTS (SSIS-Paket zum Importieren / Exportieren von Daten) verwenden, um alle Daten schnell in Ihre neue eindeutig indizierte Tabelle zu übertragen. Für 7 Millionen Reihen dauert es nur wenige Minuten.
quelle
Mit der folgenden Abfrage können wir doppelte Datensätze löschen, die auf der einzelnen oder mehreren Spalten basieren. Die folgende Abfrage wird basierend auf zwei Spalten gelöscht. Tabellenname ist:
testing
und Spaltennamenempno,empname
quelle
Erstellen Sie eine neue leere Tabelle mit derselben Struktur
Führen Sie die Abfrage wie folgt aus
Führen Sie dann diese Abfrage aus
quelle
Dies ist der einfachste Weg, um doppelte Datensätze zu löschen
http://askme.indianyouth.info/details/how-to-dumplicate-record-from-table-in-using-sql-105
quelle
Ich würde diesen Ansatz erwähnen, da er hilfreich sein kann und auf allen SQL-Servern funktioniert: Ziemlich oft gibt es nur ein - zwei Duplikate, und IDs und Anzahl der Duplikate sind bekannt. In diesem Fall:
quelle
Ich weiß nicht, wie gut es funktionieren würde, aber ich denke, Sie könnten einen Auslöser schreiben, um dies zu erzwingen, selbst wenn Sie es nicht direkt mit einem Index tun könnten. Etwas wie:
Außerdem klingt varchar (2048) für mich faul (einige Dinge im Leben sind 2048 Bytes, aber es ist ziemlich ungewöhnlich); sollte es wirklich nicht varchar (max) sein?
quelle
Eine andere Möglichkeit, dies zu tun:
quelle
quelle
quelle
Ich möchte eine Vorschau der Zeilen anzeigen, die Sie entfernen möchten, und die Kontrolle darüber behalten, welche der doppelten Zeilen beibehalten werden sollen. Siehe http://developer.azurewebsites.net/2014/09/better-sql-group-by-find-duplicate-data/
quelle