Tengo una tabla con los siguientes campos:
id (Unique)
url (Unique)
title
company
site_id
Ahora, necesito eliminar las filas que tienen lo mismo title, company and site_id
. Una forma de hacerlo será usar el siguiente SQL junto con un script ( PHP
):
SELECT title, site_id, location, id, count( * )
FROM jobs
GROUP BY site_id, company, title, location
HAVING count( * ) >1
Después de ejecutar esta consulta, puedo eliminar duplicados usando un script del lado del servidor.
Pero, quiero saber si esto se puede hacer solo usando la consulta SQL.
mysql
sql
duplicates
Chetan
fuente
fuente
Respuestas:
Una forma realmente fácil de hacer esto es agregar un
UNIQUE
índice en las 3 columnas. Cuando escriba laALTER
declaración, incluya laIGNORE
palabra clave. Al igual que:Esto eliminará todas las filas duplicadas. Como beneficio adicional, el futuro
INSERTs
que son duplicados será un error. Como siempre, es posible que desee realizar una copia de seguridad antes de ejecutar algo como esto ...fuente
set session old_alter_table=1;
Si no desea alterar las propiedades de la columna, puede usar la consulta a continuación.
Como tiene una columna que tiene ID únicos (por ejemplo,
auto_increment
columnas), puede usarla para eliminar los duplicados:En MySQL, puede simplificarlo aún más con el operador igual seguro NULL (también conocido como "operador de nave espacial" ):
fuente
MySQL tiene restricciones para referirse a la tabla de la que está eliminando. Puede solucionar eso con una tabla temporal, como:
De la sugerencia de Kostanos en los comentarios:
La única consulta lenta anterior es ELIMINAR, para los casos en que tiene una base de datos muy grande. Esta consulta podría ser más rápida:
fuente
DELETE FROM YourTable USING YourTable, tmpTable WHERE YourTable.id=tmpTable.id
DELETE
, sino tambiénINSERT
a la mesa temporal, me llevó mucho tiempo. Entonces, un índice para la tabla tmp podría ayudar muchocreate index tmpTable_id_index on tmpTable (id)
, al menos para mí.create temporary table tmpTable (id int, PRIMARY KEY (id));
Si la
IGNORE
declaración no funciona como en mi caso, puede usar la siguiente declaración:fuente
La eliminación de duplicados en las tablas de MySQL es un problema común, que generalmente es el resultado de una restricción que falta para evitar esos duplicados de antemano. Pero este problema común generalmente viene con necesidades específicas ... que requieren enfoques específicos. El enfoque debe ser diferente según, por ejemplo, el tamaño de los datos, la entrada duplicada que se debe mantener (generalmente la primera o la última), si hay índices que se deben mantener o si queremos realizar cualquier otro acción sobre los datos duplicados.
También hay algunas especificidades en MySQL en sí, como no poder hacer referencia a la misma tabla en una causa FROM al realizar una ACTUALIZACIÓN de tabla (generará el error de MySQL # 1093). Esta limitación se puede superar mediante el uso de una consulta interna con una tabla temporal (como se sugiere en algunos enfoques anteriores). Pero esta consulta interna no funcionará especialmente bien cuando se trata con grandes fuentes de datos.
Sin embargo, existe un mejor enfoque para eliminar duplicados, que es eficiente y confiable, y que puede adaptarse fácilmente a diferentes necesidades.
La idea general es crear una nueva tabla temporal, generalmente agregando una restricción única para evitar más duplicados, e INSERTAR los datos de su tabla anterior en la nueva, mientras se ocupan de los duplicados. Este enfoque se basa en consultas simples de INSERT de MySQL, crea una nueva restricción para evitar más duplicados y omite la necesidad de utilizar una consulta interna para buscar duplicados y una tabla temporal que debe mantenerse en la memoria (por lo tanto, también se ajustan a grandes fuentes de datos).
Así es como se puede lograr. Dado que tenemos una tabla de empleados , con las siguientes columnas:
Para eliminar las filas con una columna ssn duplicada y mantener solo la primera entrada encontrada, se puede seguir el siguiente proceso:
Explicación técnica
⇒ Usando este enfoque, 1.6M registros se convirtieron en 6k en menos de 200s.
Chetan , siguiendo este proceso, puede eliminar rápida y fácilmente todos sus duplicados y crear una restricción ÚNICA ejecutando:
Por supuesto, este proceso puede modificarse aún más para adaptarlo a diferentes necesidades al eliminar duplicados. Algunos ejemplos siguen.
✔ Variación para mantener la última entrada en lugar de la primera
A veces necesitamos mantener la última entrada duplicada en lugar de la primera.
✔ Variación para realizar algunas tareas en los duplicados, por ejemplo, llevar un recuento de los duplicados encontrados
A veces necesitamos realizar un procesamiento adicional en las entradas duplicadas que se encuentran (como mantener un recuento de los duplicados).
✔ Variación para regenerar la identificación de campo incremental automático
A veces usamos un campo de incremento automático y, para mantener el índice lo más compacto posible, podemos aprovechar la eliminación de los duplicados para regenerar el campo de incremento automático en la nueva tabla temporal.
✔ Otras variaciones
Muchas modificaciones adicionales también son factibles dependiendo del comportamiento deseado. Como ejemplo, las siguientes consultas utilizarán una segunda tabla temporal para, además de 1) mantener la última entrada en lugar de la primera; y 2) aumentar un contador en los duplicados encontrados; también 3) regenere la identificación de campo incremental automático mientras mantiene el orden de entrada como estaba en los datos anteriores.
fuente
Hay otra solución:
fuente
Si tiene una tabla grande con una gran cantidad de registros, las soluciones anteriores no funcionarán o tomarán demasiado tiempo. Entonces tenemos una solución diferente
fuente
Tengo este snipet de consulta para SQLServer pero creo que se puede usar en otros DBMS con pequeños cambios:
Olvidé decirte que esta consulta no elimina la fila con la identificación más baja de las filas duplicadas. Si esto funciona para usted, intente esta consulta:
fuente
ERROR 1093: You can't specify target table 'Table' for update in FROM clause
"You can't specify target table 'Table' for update in FROM..."
error, use:DELETE FROM Table WHERE Table.idTable IN ( SELECT MAX(idTable) FROM (SELECT * FROM idTable) AS tmp GROUP BY field1, field2, field3 HAVING COUNT(*) > 1)
que obliga a MySQL a crear una tabla temporal. Sin embargo, es muy lento en grandes conjuntos de datos ... en tales casos, recomendaré el código de Andomar, que es mucho más rápido.La forma más rápida es insertar filas distintas en una tabla temporal. Usando eliminar, me tomó algunas horas eliminar duplicados de una tabla de 8 millones de filas. Usando inserto y distinto, tomó solo 13 minutos.
fuente
TRUNCATE TABLE tableName
y la quinta línea debería decirINSERT INTO tableName SELECT * FROM tempTableName;
Una solución que es simple de entender y funciona sin clave primaria:
1) agregar una nueva columna booleana
2) agregue una restricción en las columnas duplicadas Y la nueva columna
3) establece la columna booleana en verdadero. Esto tendrá éxito solo en una de las filas duplicadas debido a la nueva restricción
4) eliminar filas que no se han marcado como mantenimiento
5) suelte la columna agregada
Le sugiero que mantenga la restricción que agregó, para evitar nuevos duplicados en el futuro.
fuente
Eliminar filas duplicadas usando la declaración DELETE JOIN MySQL le proporciona la declaración DELETE JOIN que puede usar para eliminar filas duplicadas rápidamente.
La siguiente instrucción elimina filas duplicadas y mantiene la identificación más alta:
fuente
Encontré una manera simple. (mantener lo último)
fuente
Simple y rápido para todos los casos:
fuente
Esto eliminará las filas duplicadas con los mismos valores para título, empresa y sitio. Se mantendrá la primera aparición y se eliminarán todos los duplicados.
fuente
Sigo visitando esta página cada vez que busco en Google "eliminar duplicados de mysql", pero para mis soluciones theIGNORE no funcionan porque tengo tablas de mysql de InnoDB
este código funciona mejor en cualquier momento
tableToclean = el nombre de la tabla que necesita limpiar
tableToclean_temp = una tabla temporal creada y eliminada
fuente
Esta solución moverá los duplicados a una tabla y los únicos a otra .
fuente
SELECT * FROM jobs GROUP BY site_id, company, title, location
?A partir de la versión 8.0 (2018), MySQL finalmente admite funciones de ventana .
Las funciones de la ventana son prácticas y eficientes. Aquí hay una solución que demuestra cómo usarlos para resolver esta tarea.
En una subconsulta, podemos usar
ROW_NUMBER()
para asignar una posición a cada registro en la tabla dentro decolumn1/column2
grupos, ordenados porid
. Si no hay duplicados, el registro obtendrá el número de fila1
. Si existe un duplicado, se numerarán de forma ascendenteid
(comenzando en1
).Una vez que los registros se numeran correctamente en la subconsulta, la consulta externa simplemente elimina todos los registros cuyo número de fila no es 1.
Consulta :
fuente
Para eliminar el registro duplicado en una tabla.
o
fuente
fuente
Para duplicar registros con columnas únicas, por ejemplo, COL1, COL2, COL3 no deben replicarse (supongamos que hemos perdido 3 columnas únicas en la estructura de la tabla y se han realizado múltiples entradas duplicadas en la tabla)
La esperanza ayudará a los desarrolladores.
fuente
TL; TR;
Puede encontrar un tutorial ampliamente descrito para resolver este problema en el sitio mysqltutorial.org :
Cómo eliminar filas duplicadas en MySQL
Se muestra muy claramente cómo eliminar filas duplicadas de tres maneras diferentes :
A) Uso de la
DELETE JOIN
declaraciónB) Usando una tabla intermedia
C) Uso de la
ROW_NUMBER()
funciónEspero que ayude a alguien.
fuente
Tengo una tabla que olvida agregar una clave principal en la fila de id. Aunque tiene auto_increment en la identificación. Pero un día, una cosa reproduce el registro de mysql bin en la base de datos que inserta algunas filas duplicadas.
Elimino la fila duplicada por
select T1.* from table_name T1 inner join (select count(*) as c,id from table_name group by id) T2 on T1.id = T2.id where T2.c > 1 group by T1.id;
eliminar las filas duplicadas por id
inserte la fila de los datos exportados.
Luego agregue la clave principal en la identificación
fuente
Me gusta ser un poco más específico en cuanto a qué registros elimino, así que aquí está mi solución:
fuente
Puede eliminar fácilmente los registros duplicados de este código.
fuente
Tuve que hacer esto con campos de texto y encontré el límite de 100 bytes en el índice.
Resolví esto agregando una columna, haciendo un hash md5 de los campos y haciendo el alter.
fuente