Eliminar filas duplicadas en SQL Server

Containers

Encontrar y eliminar filas duplicadas en SQL Server según criterios específicos, es una tarea bastante común cuando trabajamos con bases de datos.

En esta publicación, aprenderá como:

  • Encontrar filas duplicadas en una tabla utilizando la función row_number .
  • Encontrar filas duplicadas en una tabla utilizando el operador de cross apply .
  • Eliminar las filas que no cumplen con los criterios.

Definir una estructura y llenarla.

En este ejemplo, creamos y llenamos una tabla llamada post_history con estas columnas id , title y create_date. Este es un script requerido.

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'post_history') AND type in (N'U'))
    BEGIN        
        DROP TABLE post_history
    END 
GO


CREATE TABLE post_history(
                            post_history_id INT IDENTITY(1,1),
                            title VARCHAR(250) NOT NULL,
                            created_date DATETIME NOT NULL,
                        )

GO
INSERT INTO dbo.post_history
(
    title,
    created_date
)
VALUES (   'Post A',    '20180101'),
       (   'Post B',    '20180201'),
       (   'Post C',    '20180301'),
       (   'Post C',    '20180304'),
       (   'Post A',    '20180110'),
       (   'Post B',    '20180211'),
       (   'Post C',    '20180302'),
       (   'Post D',    '20180302')
       


SELECT * 
    FROM dbo.post_history AS PH
    ORDER BY PH.title, ph.created_date ASC

Después de ejecutar el script anterior, este será el resultado.

El objetivo será eliminar filas duplicadas y solo mantener la primera ingresada de acuerdo con el campo create_date y el campo con el que identificaremos si el registro está duplicado o no será el title.

Eliminar filas duplicadas con la función row_number

En la siguiente instrucción, procedemos a asignar una posición a cada registro dentro de cada grupo de title, tomando el campo created_date como criterio de ordenamiento. En este caso, ordenamos en ascendentemente, ya que desea eliminar todos los registros excepto el primer registro ingresado cronológicamente.

SELECT  ROW_NUMBER() OVER(PARTITION BY ph.title ORDER BY PH.created_date ASC) Position,
        ph.title,
        ph.created_date 
    FROM dbo.post_history AS PH

Una vez que se ha asignado una posición, el siguiente paso es eliminar todos los registros cuya posición es mayor que 1.

DELETE FROM dbo.post_history
	WHERE post_history_id IN 
            (
                SELECT X.post_history_id
                    FROM (
                            SELECT  ROW_NUMBER() OVER(PARTITION BY ph.title 
                                    ORDER BY PH.created_date ASC) Position,
                                    PH.post_history_id
                                FROM dbo.post_history AS PH
                        ) X
                    WHERE X.Position >1
                )

Con las instrucciones anteriores, la tabla de datos será la siguiente.

Eliminar filas duplicadas con el operador cross_apply

Del mismo modo, podemos usar la instrucción CROSS APPLY para identificar y eliminar filas. En esta variante, crea una subconsulta con los títulos y para cada consulta y obtiene a través deL CROSS APPLY el primer registro coincidente y, por lo tanto, se utiliza una eliminación con la instrucción NOT IN.

DELETE FROM dbo.post_history
WHERE post_history_id 
        NOT IN (
                SELECT PH.post_history_id
                FROM (
                    SELECT PH.title 
                        FROM dbo.post_history AS PH 
                        GROUP BY PH.title) Titles
                    CROSS APPLY
                    (
                        SELECT TOP (1)
                            PH.post_history_id
                        FROM dbo.post_history AS PH
                        WHERE PH.title = Titles.title
                        ORDER BY PH.created_date ASC
                    ) PH
            );

Conclusiones

¿Cuál es la forma correcta de eliminar filas duplicadas? Esto dependerá de cada escenario y debe ser analizado y probado. ¿Tiene otros estilos para borrar estos datos? Por favor coméntanos.


Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *