with cte as (
select row_number() over (partition by dupcol1, dupcol2 order by ID) as rn
from table)
delete from cte
where rn > 2; -- or >3 etc
Die Abfrage erstellt eine „Zeilennummer“ für jeden Datensatz, gruppiert nach (dupcol1, dupcol2) und sortiert nach ID. Tatsächlich zählt diese Zeilennummer 'Duplikate', die dieselbe dupcol1 und dupcol2 haben, und weist dann die Nummer 1, 2, 3.. N zu, sortiert nach ID. Wenn Sie nur 2 'Duplikate' behalten möchten, müssen Sie diejenigen löschen, denen die Nummern 3,4,.. N
zugewiesen wurden und das ist der Teil, den DELLETE.. WHERE rn > 2;
übernimmt
Mit dieser Methode können Sie den ORDER BY
ändern passend zu Ihrer bevorzugten Reihenfolge (z. B. ORDER BY ID DESC
), sodass die LATEST
hat rn=1
, dann ist das vorletzte rn=2 und so weiter. Der Rest bleibt gleich, das DELETE
entfernt nur die ältesten, da sie die höchsten Zeilennummern haben.
Im Gegensatz zu diese eng verwandte Frage , je komplexer die Bedingung wird, desto einfacher wird die Verwendung von CTEs und row_number(). Die Leistung kann immer noch problematisch sein, wenn kein richtiger Zugriffsindex vorhanden ist.