¿Cuál es la mejor manera de eliminar filas duplicadas de una SQL Server
tabla bastante grande (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
sql-server
tsql
duplicates
Seibar
fuente
fuente
DELETE FROM
un término CTE directamente. Ver stackoverflow.com/q/18439054/398670ROWID()
función por la columna RowID, si corresponde)Respuestas:
Suponiendo que no hay
GROUP BY
valores nulos, las columnas únicas ySELECT
elMIN (or MAX)
RowId como la fila para mantener. Luego, simplemente elimine todo lo que no tenía una ID de fila:En caso de que tenga un GUID en lugar de un entero, puede reemplazar
con
fuente
DELETE FROM MyTable WHERE RowId NOT IN (SELECT MIN(RowId) FROM MyTable GROUP BY Col1, Col2, Col3);
LEFT JOIN
es menos eficiente queNOT EXISTS
sqlinthewild.co.za/index.php/2010/03/23/... El mismo sitio también comparaNOT IN
vsNOT EXISTS
. sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in De los 3, creo queNOT EXISTS
funciona mejor. Los tres generarán un plan con una unión automática, aunque eso se puede evitar.DELETE MyTable FROM MyTable
la sintaxis correcta? No veo poner el nombre de la tabla justo después delDELETE
como una opción en la documentación aquí . Lo siento si esto es obvio para los demás; Soy un novato en SQL tratando de aprender. Más importante que por qué funciona: ¿cuál es la diferencia entre incluir el nombre de la tabla allí o no?Otra posible forma de hacerlo es
Estoy usando lo
ORDER BY (SELECT 0)
anterior, ya que es arbitrario qué fila conservar en caso de empate.Para conservar el último en
RowID
orden, por ejemplo, podría usarORDER BY RowID DESC
Planes de ejecucion
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 autounión.
Esto no es siempre el caso, sin embargo. Un lugar donde se
GROUP BY
podría preferir la solución son las situaciones en las que se elegiría un agregado de hash en lugar de un agregado de flujo.La
ROW_NUMBER
solución siempre dará el mismo plan, mientras que laGROUP BY
estrategia es más flexible.Los factores que podrían favorecer el enfoque agregado de hash serían
En las 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
copiar el original y copiarlo de nuevo para minimizar el registro en comparación con eliminar un Muy alta proporción de las filas.fuente
uniqueidentifier
. Este es mucho más simple y funciona perfectamente en cualquier mesa. Gracias martinRowId
) para comparar.Hay un buen artículo sobre la eliminación de duplicados en el sitio de soporte de Microsoft. Es bastante conservador: hacen que hagas todo en pasos separados, pero debería funcionar bien en tablas grandes.
He usado autouniones para hacer esto en el pasado, aunque probablemente podría ser mejorado con una cláusula HAVING:
fuente
La siguiente consulta es útil para eliminar filas duplicadas. La tabla en este ejemplo tiene
ID
como columna de identidad y las columnas que tienen datos duplicados sonColumn1
,Column2
yColumn3
.El uso de secuencias de comandos siguientes espectáculos de
GROUP BY
,HAVING
,ORDER BY
en una consulta y devuelve los resultados con la columna duplicado y su recuento.fuente
NOT IN
menudo funciona mejor queOUTER JOIN ... NULL
. Agregaría unHAVING MAX(ID) IS NOT NULL
a la consulta aunque, aunque semánticamente, no debería ser necesario, ya que eso puede mejorar el ejemplo delPostgres:
fuente
fuente
Esto eliminará filas duplicadas, excepto la primera fila
Consulte ( http://www.codeproject.com/Articles/157977/Remove-Duplicate-Rows-from-a-Table-in-SQL-Server )
fuente
Preferiría CTE para eliminar filas duplicadas de la tabla del servidor sql
recomiendo seguir este artículo :: http://codaffection.com/sql-server-article/delete-duplicate-rows-in-sql-server/
fuente
Para obtener filas duplicadas:
Para eliminar las filas duplicadas:
fuente
DELETE FROM
, en segundo lugar, no funcionará, porque no puede hacerloSELECT
desde la misma tabla de la queDELETE
proviene. En MySQL esto despegaMySQL error 1093
.Rápido y sucio para eliminar filas duplicadas exactas (para tablas pequeñas):
fuente
Prefiero la solución subquery \ having count (*)> 1 a la combinación interna porque me resultó más fácil de leer y fue muy fácil convertirla en una instrucción SELECT para verificar qué se eliminaría antes de ejecutarla.
fuente
MAX(id)
para eliminar los últimos duplicados, y lo agreguéLIMIT 1000000
a la consulta interna para que no tuviera que escanear toda la tabla. Esto mostró un progreso mucho más rápido que las otras respuestas, que parecerían bloquearse durante horas. Después de podar la tabla a un tamaño manejable, puede finalizar con las otras consultas. Consejo: asegúrese de que col1 / col2 / col3 tenga índices para agrupar por.fuente
Pensé en compartir mi solución, ya que funciona en circunstancias especiales. En mi caso, la tabla con valores duplicados no tenía una clave externa (porque los valores se duplicaron de otra base de datos).
PD: cuando trabajo en cosas como esta, siempre uso una transacción, esto no solo garantiza que todo se ejecute en su conjunto, sino que también me permite probar sin arriesgar nada. Pero, por supuesto, deberías hacer una copia de seguridad de todos modos solo para estar seguro ...
fuente
Esta consulta mostró muy buen rendimiento para mí:
eliminó 1M de filas en poco más de 30 segundos de una tabla de 2M (50% de duplicados)
fuente
Usando CTE. La idea es unirse en una o más columnas que formen un registro duplicado y luego eliminar lo que desee:
fuente
Otra solución fácil se puede encontrar en el enlace pegado aquí . Éste es fácil de entender y parece ser efectivo para la mayoría de los problemas similares. Sin embargo, es para SQL Server, pero el concepto utilizado es más que aceptable.
Estas son las partes relevantes de la página vinculada:
Considere estos datos:
Entonces, ¿cómo podemos eliminar esos datos duplicados?
Primero, inserte una columna de identidad en esa tabla utilizando el siguiente código:
Use el siguiente código para resolverlo:
fuente
ROW_NUMBER
versión funciona bien para ese caso sin necesidad de agregar una nueva columna antes de comenzar.Aquí hay otro buen artículo sobre la eliminación de duplicados .
Discute por qué es difícil: " SQL se basa en álgebra relacional, y los duplicados no pueden ocurrir en álgebra relacional, porque los duplicados no están permitidos en un conjunto. "
La solución de la tabla temporal y dos ejemplos de mysql.
En el futuro, lo evitará a nivel de base de datos o desde la perspectiva de una aplicación. Sugeriría el nivel de la base de datos porque su base de datos debería ser responsable de mantener la integridad referencial, los desarrolladores solo causarán problemas;)
fuente
Oh, por supuesto. Usa una tabla temporal. Si desea una declaración única, no muy eficaz que "funcione", puede ir con:
Básicamente, para cada fila de la tabla, la sub-selección encuentra el RowID superior de todas las filas que son exactamente como la fila en consideración. Entonces terminas con una lista de RowID que representan las filas "originales" no duplicadas.
fuente
Tenía una tabla donde necesitaba preservar filas no duplicadas. No estoy seguro de la velocidad o la eficiencia.
fuente
HAVING COUNT(*) > 1
?Utilizar este
fuente
La otra forma es crear una nueva tabla con los mismos campos y con índice único . Luego mueva todos los datos de la tabla anterior a la nueva tabla . SQL Server automáticamente ignora (también hay una opción sobre qué hacer si habrá un valor duplicado: ignorar, interrumpir o algo) valores duplicados. Entonces tenemos la misma tabla sin filas duplicadas. Si no desea un índice único, después de la transferencia de datos puede soltarlo .
Especialmente para tablas más grandes , puede usar DTS (paquete SSIS para importar / exportar datos) para transferir todos los datos rápidamente a su nueva tabla indexada de forma única. Para 7 millones de filas, solo lleva unos minutos.
fuente
Al utilizar la consulta a continuación, podemos eliminar registros duplicados basados en la columna única o en la columna múltiple. la consulta a continuación se elimina en base a dos columnas. el nombre de la tabla es:
testing
y los nombres de columnaempno,empname
fuente
Crear una nueva tabla en blanco con la misma estructura.
Ejecute una consulta como esta
Luego ejecute esta consulta
fuente
Esta es la forma más fácil de eliminar registros duplicados
http://askme.indianyouth.info/details/how-to-dumplicate-record-from-table-in-using-sql-105
fuente
Mencionaría este enfoque, así como puede ser útil, y funciona en todos los servidores SQL: a menudo solo hay uno: dos duplicados, y se conocen los ID y el recuento de duplicados. En este caso:
fuente
No sé qué tan bien funcionaría, pero creo que podrías escribir un disparador para hacer cumplir esto, incluso si no pudieras hacerlo directamente con un índice. Algo como:
Además, varchar (2048) me suena sospechoso (algunas cosas en la vida son 2048 bytes, pero es bastante raro); ¿Realmente no debería ser varchar (max)?
fuente
Otra forma de hacer esto: -
fuente
fuente
fuente
Desea obtener una vista previa de las filas que está a punto de eliminar y mantener el control sobre cuál de las filas duplicadas mantener. Ver http://developer.azurewebsites.net/2014/09/better-sql-group-by-find-duplicate-data/
fuente