Pregunta ¿Cómo puedo eliminar filas duplicadas?


¿Cuál es la mejor manera de eliminar filas duplicadas de una bastante grande SQL Server tabla (es decir, más de 300,000 filas)

Las filas, por supuesto, no serán duplicados perfectos debido a la existencia del RowID campo de identidad.

Mi mesa

RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null

1160
2017-08-20 21:51


origen


Respuestas:


Suponiendo que no hay nulos, GROUP BY las columnas únicas, y SELECT el MIN (or MAX) RowId como la fila para mantener. Luego, simplemente borre todo lo que no tenía una identificación de fila:

DELETE FROM MyTable
LEFT OUTER JOIN (
   SELECT MIN(RowId) as RowId, Col1, Col2, Col3 
   FROM MyTable 
   GROUP BY Col1, Col2, Col3
) as KeepRows ON
   MyTable.RowId = KeepRows.RowId
WHERE
   KeepRows.RowId IS NULL

En caso de que tenga un GUID en lugar de un número entero, puede reemplazar

MIN(RowId)

con

CONVERT(uniqueidentifier, MIN(CONVERT(char(36), MyGuidColumn)))

1062
2017-08-20 22:00



Otra posible forma de hacerlo es

; 

--Ensure that any immediately preceding statement is terminated with a semicolon above
WITH cte
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3 
                                       ORDER BY ( SELECT 0)) RN
         FROM   #MyTable)
DELETE FROM cte
WHERE  RN > 1;

estoy usando ORDER BY (SELECT 0) arriba ya que es arbitrario qué fila conservar en caso de empate.

Para preservar el último en RowID Por ejemplo, puede usar ORDER BY RowID DESC 

Planes de ejecución

El plan de ejecución para esto es a menudo más simple y más eficiente que el de la respuesta aceptada, ya que no requiere la unión automática.

Execution Plans

Esto no es siempre el caso, sin embargo. Un lugar donde el GROUP BY solución puede ser preferida es situaciones donde una agregado de hash se elegiría con preferencia a un agregado de flujo.

los ROW_NUMBER solución siempre dará más o menos el mismo plan mientras que el GROUP BY la estrategia es más flexible.

Execution Plans

Los factores que podrían favorecer el enfoque agregado de hash serían

  • Ningún índice útil en las columnas de particionamiento
  • relativamente menos grupos con relativamente más duplicados en cada grupo

En versiones extremas de este segundo caso (si hay muy pocos grupos con muchos duplicados en cada uno), también se podría considerar simplemente insertar las filas para mantenerlas en una nueva tabla, luego TRUNCATE-ing el original y copiando de nuevo para minimizar el registro en comparación con la eliminación de una gran proporción de las filas.


700
2017-09-29 14:52



Hay un buen artículo sobre eliminando duplicados en el sitio de soporte de Microsoft. Es bastante conservador: hacen que hagas todo en pasos separados, pero debería funcionar bien en mesas grandes.

He usado autocombinaciones para hacer esto en el pasado, aunque probablemente podría estar preciado con una cláusula HAVING:

DELETE dupes
FROM MyTable dupes, MyTable fullTable
WHERE dupes.dupField = fullTable.dupField 
AND dupes.secondDupField = fullTable.secondDupField 
AND dupes.uniqueField > fullTable.uniqueField

132
2017-08-20 21:53



La siguiente consulta es útil para eliminar filas duplicadas. La tabla en este ejemplo tiene ID como una columna de identidad y las columnas que tienen datos duplicados son Column1, Column2 y Column3.

DELETE FROM TableName
WHERE  ID NOT IN (SELECT MAX(ID)
                  FROM   TableName
                  GROUP  BY Column1,
                            Column2,
                            Column3
                  /*Even if ID is not null-able SQL Server treats MAX(ID) as potentially
                    nullable. Because of semantics of NOT IN (NULL) including the clause
                    below can simplify the plan*/
                  HAVING MAX(ID) IS NOT NULL) 

La siguiente secuencia de comandos muestra el uso de GROUP BY, HAVING, ORDER BY en una consulta, y devuelve los resultados con una columna duplicada y su conteo.

SELECT YourColumnName,
       COUNT(*) TotalCount
FROM   YourTableName
GROUP  BY YourColumnName
HAVING COUNT(*) > 1
ORDER  BY COUNT(*) DESC 

87
2017-11-23 15:32



delete t1
from table t1, table t2
where t1.columnA = t2.columnA
and t1.rowid>t2.rowid

Postgres:

delete
from table t1
using table t2
where t1.columnA = t2.columnA
and t1.rowid > t2.rowid

52
2017-09-30 02:35



DELETE LU 
FROM   (SELECT *, 
               Row_number() 
                 OVER ( 
                   partition BY col1, col1, col3 
                   ORDER BY rowid DESC) [Row] 
        FROM   mytable) LU 
WHERE  [row] > 1 

41
2018-05-21 07:54



Esto eliminará las filas duplicadas, excepto la primera fila

DELETE
FROM
    Mytable
WHERE
    RowID NOT IN (
        SELECT
            MIN(RowID)
        FROM
            Mytable
        GROUP BY
            Col1,
            Col2,
            Col3
    )

Refer (http://www.codeproject.com/Articles/157977/Remove-Duplicate-Rows-from-a-Table-in-SQL-Server)


36
2017-09-10 13:07



Preferiría que CTE elimine filas duplicadas de la tabla del servidor sql

Recomiendo encarecidamente seguir este artículo ::http://dotnetmob.com/sql-server-article/delete-duplicate-rows-in-sql-server/

manteniendo el original

WITH CTE AS
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY col1,col2,col3 ORDER BY col1,col2,col3) AS RN
FROM MyTable
)

DELETE FROM CTE WHERE RN<>1

sin guardar original

WITH CTE AS
(SELECT *,R=RANK() OVER (ORDER BY col1,col2,col3)
FROM MyTable)
 
DELETE CTE
WHERE R IN (SELECT R FROM CTE GROUP BY R HAVING COUNT(*)>1)

22
2018-05-19 14:35



Rápido y sucio para eliminar filas duplicadas exactas (para tablas pequeñas):

select  distinct * into t2 from t1;
delete from t1;
insert into t1 select *  from t2;
drop table t2;

21
2018-02-05 21:44