Blog dedicado a la programación y a la informática en general

Ir al contenido | Ir al menú | Ir a las búsquedas

Eliminar registros duplicados en Oracle

oracle-logo.png

En el siguiente tip podremos ver cómo eliminar de una tabla los registros duplicados en Oracle, para ello usaremos la función rank y el rowid.

Para el ejemplo tomemos la siguiente tabla como ejemplo:

CREATE TABLE datos_duplicados
(
   id_reg NUMBER (10) PRIMARY KEY NOT NULL,
   nombre VARCHAR (50) NOT NULL
);

// Con registros:

INSERT INTO DATOS_DUPLICADOS (ID_REG, NOMBRE) Values (1, 'Ana');
INSERT INTO DATOS_DUPLICADOS (ID_REG, NOMBRE) Values (2, 'Blanca');
INSERT INTO DATOS_DUPLICADOS (ID_REG, NOMBRE) Values (3, 'Rubén');
INSERT INTO DATOS_DUPLICADOS (ID_REG, NOMBRE) Values (4, 'Blanca');
INSERT INTO DATOS_DUPLICADOS (ID_REG, NOMBRE) Values (5, 'Ana');

Como vemos Ana y Blanca están repetidos, y nosotros queremos quedarnos solo con el primer registro de cada uno además del resto que no está duplicado.

Con la función rank le asignaremos una posición a cada registro agrupados por nombre, además obtenemos el rowid de cada fila:

select nombre, rank() over (partition by NOMBRE order by rowid) rnk, rowid as "rowid" from datos_duplicados;

NOMBRE       RNK rowid             
--------- ------ ------------------
Blanca         1 AAA/faAAFAAAOKxAAB
Blanca         2 AAA/faAAFAAAOKxAAF
Ana            1 AAA/faAAFAAAOKxAAA
Ana            2 AAA/faAAFAAAOKxAAG
Rubén          1 AAA/faAAFAAAOKxAAC

5 rows selected.

Ahora solo tenemos que filtrar para quedarnos con los registros que no tengan la primera posición (rnk > 1):

select "rowid", rnk from (
    select nombre, rank() over (partition by NOMBRE order by rowid) rnk, rowid as "rowid" from datos_duplicados
) where rnk > 1;

rowid                 RNK
------------------ ------
AAA/faAAFAAAOKxAAF      2
AAA/faAAFAAAOKxAAG      2

2 rows selected.

Ya por último eliminamos los registros utilizando los rowid que hemos obtenido, como voy a usar IN tendré que hacer una subconsulta extra para obtener solo la columna "rowid":

delete from datos_duplicados where rowid in (
    select "rowid" from (
        select "rowid", rnk from (
            select nombre, rank() over (partition by NOMBRE order by rowid) rnk, rowid as "rowid" from datos_duplicados
        ) where rnk > 1
    )
);

2 rows deleted.

// Comprobamos los registros:

SELECT * FROM datos_duplicados;

 ID_REG NOMBRE  
------- --------
      1 Ana     
      2 Blanca  
      3 Rubén   

3 rows selected.

Y eso es todo.

Saludos!

Comentarios

1. El Viernes, 7 de Septiembre de 2018, 08:18 por Fernando

Eres un Genio!
Tenia horas buscando esta solución,
Muchas gracias

2. El Jueves, 12 de Marzo de 2020, 13:55 por cristian

muchas gracias! muy bien explicado y funciona perfecto!

3. El Martes, 14 de Abril de 2020, 21:24 por Vero

Gracias totales, justo lo que buscaba.

4. El Jueves, 20 de Octubre de 2022, 03:01 por Flaka

Super! Excelente solución, felicidades!

Añadir un comentario

El código HTML se muestra como texto y las direcciones web se transforman automáticamente.

Discusiones sobre el mismo tema

URL de retroenlace : https://www.dosmweb.com/blog/index.php?trackback/25

Fuente de los comentarios de esta entrada