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
Zapytanie generuje „numer wiersza” dla każdego rekordu, pogrupowany według (dupcol1, dupcol2) i uporządkowany według identyfikatora. W efekcie ten numer wiersza zlicza 'duplikaty', które mają te same dupcol1 i dupcol2 i przypisuje im numer 1, 2, 3. N, porządek według ID. Jeśli chcesz zachować tylko 2 'duplikaty', musisz usunąć te, którym przypisano numery 3,4,.. N
i to jest część, którą zajmuje się DELLETE.. WHERE rn > 2;
Za pomocą tej metody możesz zmienić ORDER BY
zgodnie z preferowaną kolejnością (np.ORDER BY ID DESC
), tak aby LATEST
ma rn=1
, następny od ostatniego to rn=2 i tak dalej. Reszta pozostaje taka sama, DELETE
usunie tylko najstarsze, ponieważ mają one najwyższe numery wierszy.
W przeciwieństwie do to ściśle powiązane pytanie , ponieważ warunek staje się bardziej złożony, używanie CTE i row_number() staje się prostsze. Wydajność może być nadal problematyczna, jeśli nie istnieje odpowiedni indeks dostępu.