Eine andere Möglichkeit ist
;
--Ensure that any immediately preceding statement is terminated with a semicolon above
WITH cte
AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3
ORDER BY ( SELECT 0)) RN
FROM #MyTable)
DELETE FROM cte
WHERE RN > 1;
Ich verwende ORDER BY (SELECT 0)
oben, da es willkürlich ist, welche Zeile im Falle eines Gleichstands erhalten bleibt.
Um die letzte in RowID
Bestellung könnten Sie zum Beispiel verwenden ORDER BY RowID DESC
Ausführungspläne
Der Ausführungsplan hierfür ist oft einfacher und effizienter als der in der akzeptierten Antwort, da er die Selbstverknüpfung nicht erfordert.
Dies ist jedoch nicht immer der Fall. Ein Ort, an dem die GROUP BY
Lösung könnte in Situationen bevorzugt werden, in denen ein Hash-Aggregat würde einem Stromaggregat vorgezogen werden.
Le site ROW_NUMBER
Lösung wird immer so ziemlich den gleichen Plan ergeben, während die GROUP BY
Die Strategie ist flexibler.
Faktoren, die für den Hash-Aggregat-Ansatz sprechen könnten, wären
- Kein nützlicher Index für die Partitionierungsspalten
- relativ wenige Gruppen mit relativ vielen Duplikaten in jeder Gruppe
In extremen Versionen dieses zweiten Falls (wenn es sehr wenige Gruppen mit vielen Duplikaten in jeder gibt) könnte man auch erwägen, die zu behaltenden Zeilen einfach in eine neue Tabelle einzufügen und dann TRUNCATE
-Originalen und dem Zurückkopieren, um die Protokollierung zu minimieren, im Vergleich zum Löschen eines sehr hohen Anteils der Zeilen.
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/3986700 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.