1375 Stimmen

Wie kann ich doppelte Zeilen entfernen?

Wie entfernt man am besten doppelte Zeilen aus einer ziemlich großen SQL Server Tabelle (d.h. 300.000+ Zeilen)?

Die Zeilen werden natürlich keine perfekten Duplikate sein, da es die RowID Identitätsfeld.

MyTable

RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null

15 Stimmen

Kleiner Tipp für PostgreSQL-Benutzer, die dies lesen (viele, wenn man bedenkt, wie oft es verlinkt wird): Pg stellt CTE-Terme nicht als aktualisierbare Views zur Verfügung, so dass Sie nicht DELETE FROM ein CTE-Begriff direkt. Siehe stackoverflow.com/q/18439054/398670

0 Stimmen

@CraigRinger das gleiche gilt für Sybase - Die übrigen Lösungen habe ich hier zusammengestellt (sollten auch für PG und andere gelten): stackoverflow.com/q/19544489/1855801 (ersetzen Sie einfach die ROWID() Funktion durch die Spalte RowID, falls vorhanden)

14 Stimmen

Ich möchte hier nur einen Vorbehalt anbringen. Wenn Sie einen Deduplizierungsprozess durchführen, überprüfen Sie immer zuerst, was Sie löschen! Dies ist einer der Bereiche, in denen es sehr häufig vorkommt, dass versehentlich gute Daten gelöscht werden.

13voto

Harikesh Yadav Punkte 165

Dies ist der einfachste Weg, einen doppelten Datensatz zu löschen

 DELETE FROM tblemp WHERE id IN 
 (
  SELECT MIN(id) FROM tblemp
   GROUP BY  title HAVING COUNT(id)>1
 )

2 Stimmen

Warum stimmt jemand für dieses Thema? Wenn Sie mehr als zwei gleiche IDs haben, wird das nicht funktionieren. Schreiben Sie stattdessen: delete from tblemp where id not in (select min(id) from tblemp group by title)

13voto

Nitish Pareek Punkte 2295

Eine weitere einfache Lösung finden Sie unter dem eingefügten Link aquí . Diese ist leicht zu verstehen und scheint für die meisten ähnlichen Probleme wirksam 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:

Beachten Sie diese Daten:

EMPLOYEE_ID ATTENDANCE_DATE
A001    2011-01-01
A001    2011-01-01
A002    2011-01-01
A002    2011-01-01
A002    2011-01-01
A003    2011-01-01

Wie können wir also diese doppelten Daten löschen?

Fügen Sie zunächst eine Identitätsspalte in diese Tabelle ein, indem Sie den folgenden Code verwenden:

ALTER TABLE dbo.ATTENDANCE ADD AUTOID INT IDENTITY(1,1)  

Verwenden Sie den folgenden Code, um das Problem zu lösen:

DELETE FROM dbo.ATTENDANCE WHERE AUTOID NOT IN (SELECT MIN(AUTOID) _
    FROM dbo.ATTENDANCE GROUP BY EMPLOYEE_ID,ATTENDANCE_DATE)

1 Stimmen

"Leicht zu verstehen", "scheint wirksam zu sein", aber kein Wort darüber, worin die Methode besteht. Stellen Sie sich vor, der Link wird ungültig, was nützt es dann, zu wissen, dass die Methode war leicht verständlich und effektiv? Bitte fügen Sie wesentliche Teile der Methodenbeschreibung in Ihren Beitrag ein, sonst ist dies keine Antwort.

0 Stimmen

Diese Methode ist nützlich für Tabellen, für die noch keine Identität definiert ist. Oft müssen Sie Duplikate loswerden, um den Primärschlüssel zu definieren!

0 Stimmen

@JeffDavis - Die ROW_NUMBER Version funktioniert in diesem Fall gut, ohne dass Sie vorher eine neue Spalte hinzufügen müssen.

12voto

Haris N I Punkte 5714

Verwenden Sie diese

WITH tblTemp as
(
SELECT ROW_NUMBER() Over(PARTITION BY Name,Department ORDER BY Name)
   As RowNumber,* FROM <table_name>
)
DELETE FROM tblTemp where RowNumber >1

11voto

Craig Punkte 1406

Hier ist ein weiterer guter Artikel über Entfernen von Duplikaten .

Sie erörtert, warum es schwierig ist: " SQL basiert auf der relationalen Algebra, und Duplikate können in der relationalen Algebra nicht vorkommen, da Duplikate in einer Menge nicht zulässig sind. "

Die Lösung mit der temporären Tabelle und zwei mysql-Beispiele.

Werden Sie dies in Zukunft auf Datenbankebene oder aus Sicht der Anwendung verhindern? Ich würde die Datenbankebene vorschlagen, weil Ihre Datenbank für die Aufrechterhaltung der referentiellen Integrität verantwortlich sein sollte, Entwickler werden einfach Probleme verursachen ;)

1 Stimmen

SQL basiert auf Multi-Sets. Aber selbst wenn es auf Mengen basieren würde, sind diese beiden Tupel (1, a) & (2, a) unterschiedlich.

11voto

Jacob Proffitt Punkte 12454

Aber sicher. Verwenden Sie eine temporäre Tabelle. Wenn Sie eine einzelne, nicht sehr performante Anweisung wollen, die "funktioniert", können Sie mit gehen:

DELETE FROM MyTable WHERE NOT RowID IN
    (SELECT 
        (SELECT TOP 1 RowID FROM MyTable mt2 
        WHERE mt2.Col1 = mt.Col1 
        AND mt2.Col2 = mt.Col2 
        AND mt2.Col3 = mt.Col3) 
    FROM MyTable mt)

Grundsätzlich findet die Unterauswahl für jede Zeile in der Tabelle die oberste RowID aller Zeilen, die genau wie die betreffende Zeile sind. Am Ende erhalten Sie also eine Liste von RowIDs, die die "ursprünglichen", nicht duplizierten Zeilen darstellen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X