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 consulta genera un 'número de fila' para cada registro, agrupados por (dupcol1, dupcol2) y ordenados por ID. En efecto, este número de fila cuenta los 'duplicados' que tienen el mismo dupcol1 y dupcol2 y asigna el número 1, 2, 3... N, ordenado por ID. Si desea mantener solo 2 'duplicados', debe eliminar aquellos a los que se les asignaron los números 3,4,.. N
y esa es la parte de la que se ocupa el DELLETE.. WHERE rn > 2;
Usando este método puedes cambiar el ORDER BY
para adaptarse a su pedido preferido (p. ej., ORDER BY ID DESC
), de modo que el LATEST
tiene rn=1
, entonces el siguiente al último es rn=2 y así sucesivamente. El resto permanece igual, el DELETE
eliminará solo los más antiguos, ya que tienen los números de fila más altos.
A diferencia de esta pregunta estrechamente relacionada , a medida que la condición se vuelve más compleja, usar CTE y row_number() se vuelve más simple. El rendimiento puede ser problemático aún si no existe un índice de acceso adecuado.