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
Forespørgslen fremstiller et 'rækkenummer' for hver post, grupperet efter (dupcol1, dupcol2) og sorteret efter ID. Dette rækkenummer tæller faktisk 'duplikater', der har samme dupcol1 og dupcol2 og tildeler derefter nummeret 1, 2, 3.. N, sorteret efter ID. Hvis du kun vil beholde 2 'duplikater', skal du slette dem, der har fået tildelt numrene 3,4,.. N
og det er den del, der tages af DELLETE.. WHERE rn > 2;
Ved at bruge denne metode kan du ændre ORDER BY
for at passe til din foretrukne ordre (f.eks.ORDER BY ID DESC
), så LATEST
har rn=1
, så er den næstsidste rn=2 og så videre. Resten forbliver den samme, DELETE
vil kun fjerne de ældste, da de har de højeste rækkenumre.
I modsætning til dette nært beslægtede spørgsmål , efterhånden som betingelsen bliver mere kompleks, bliver brugen af CTE'er og row_number() enklere. Ydeevne kan stadig være problematisk, hvis der ikke findes et korrekt adgangsindeks.