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
Frågan tillverkar ett "radnummer" för varje post, grupperat efter (dupcol1, dupcol2) och sorterat efter ID. I själva verket räknar detta radnummer "dubbletter" som har samma dupcol1 och dupcol2 och tilldelar sedan numret 1, 2, 3.. N, ordning efter ID. Om du bara vill behålla 2 "dubbletter", måste du ta bort de som tilldelats numren 3,4,.. N
och det är den del som tas om hand av DELLETE.. WHERE rn > 2;
Med den här metoden kan du ändra ORDER BY
för att passa din föredragna beställning (t.ex.ORDER BY ID DESC
), så att LATEST
har rn=1
, sedan är näst senaste rn=2 och så vidare. Resten förblir detsamma, DELETE
tar bara bort de äldsta eftersom de har de högsta radnumren.
Till skillnad från denna närbesläktade fråga , när villkoret blir mer komplext, blir det enklare att använda CTE och row_number(). Prestanda kan fortfarande vara problematisk om det inte finns något korrekt åtkomstindex.