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
Заявката произвежда „номер на ред“ за всеки запис, групиран по (dupcol1, dupcol2) и подреден по ID. Всъщност този номер на ред брои „дубликати“, които имат едни и същи dupcol1 и dupcol2 и присвоява след това числото 1, 2, 3.. N, подредени по ID. Ако искате да запазите само 2 „дубликати“, тогава трябва да изтриете тези, на които са присвоени номера 3,4,.. N
и това е частта, за която се грижи DELLETE.. WHERE rn > 2;
С помощта на този метод можете да промените ORDER BY
за да отговарят на предпочитаната от вас поръчка (напр.ORDER BY ID DESC
), така че LATEST
има rn=1
, тогава следващият най-късен е rn=2 и така нататък. Останалото остава същото, DELETE
ще премахне само най-старите, тъй като те имат най-високите номера на редовете.
За разлика от този тясно свързан въпрос , тъй като условието става по-сложно, използването на CTE и row_number() става по-просто. Производителността все още може да бъде проблематична, ако не съществува правилен индекс за достъп.