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
A consulta está fabricando um 'número de linha' para cada registro, agrupado por (dupcol1, dupcol2) e ordenado por ID. Com efeito, este número de linha conta 'duplicatas' que têm o mesmo dupcol1 e dupcol2 e atribui então o número 1, 2, 3.. N, ordem por ID. Se você quiser manter apenas 2 'duplicatas', então você precisa deletar aqueles que receberam os números
3,4,.. N
e essa é a parte cuidada pelo DELLETE.. WHERE rn > 2;
Usando este método, você pode alterar o
ORDER BY
para se adequar ao seu pedido preferido (por exemplo, ORDER BY ID DESC
), para que o LATEST
tem rn=1
, então o próximo ao mais recente é rn=2 e assim por diante. O resto permanece o mesmo, o DELETE
removerá apenas os mais antigos, pois eles têm os números de linha mais altos. Ao contrário de esta pergunta intimamente relacionada , à medida que a condição se torna mais complexa, usar CTEs e row_number() se torna mais simples. O desempenho ainda pode ser problemático se não existir um índice de acesso adequado.