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
La query produce un "numero di riga" per ogni record, raggruppato per (dupcol1, dupcol2) e ordinato per ID. In effetti questo numero di riga conta i "duplicati" che hanno lo stesso dupcol1 e dupcol2 e assegna quindi il numero 1, 2, 3.. N, ordina per ID. Se vuoi conservare solo 2 'duplicati', devi eliminare quelli a cui sono stati assegnati i numeri 3,4,.. N
e questa è la parte curata dal DELLETE.. WHERE rn > 2;
Usando questo metodo puoi cambiare il ORDER BY
per soddisfare il tuo ordine preferito (es.ORDER BY ID DESC
), in modo che il LATEST
ha rn=1
, quindi il prossimo all'ultimo è rn=2 e così via. Il resto rimane lo stesso, il DELETE
rimuoverà solo i più vecchi poiché hanno i numeri di riga più alti.
A differenza di questa domanda strettamente correlata , poiché la condizione diventa più complessa, l'utilizzo di CTE e row_number() diventa più semplice. Le prestazioni potrebbero essere ancora problematiche se non esiste un adeguato indice di accesso.