¿Cómo eliminar duplicados en una tabla MySQL?

158

Necesito DELETEfilas duplicadas para el sid especificado en una MySQLtabla.

¿Cómo puedo hacer esto con una consulta SQL?

DELETE (DUPLICATED TITLES) FROM table WHERE SID = "1"

Algo así, pero no sé cómo hacerlo.

Ali Demirci
fuente
¿Solo necesita hacerlo una vez o debe hacerlo todo el tiempo?
Billy ONeal
¿Los registros con los registros duplicados tienen todos los mismos datos o el resto de los campos son diferentes entre sí? Si tiene la primera opción, simplemente puede eliminar todos los registros, pero uno, si tiene la segunda opción, ¿cómo determina qué registro desea mantener?
rael_kid
@Lex Primera opción. @ Billy, necesito hacerlo todo el tiempo.
Ali Demirci
1
posible duplicado de Eliminar filas duplicadas en MySQL
Basilevs
1
Hay muchas cosas que han cambiado aquí en varias versiones de MySQL. Verifique su versión de MySQL cuidadosamente antes de saltar por el camino de cualquiera de las soluciones aquí.
delatbabel

Respuestas:

215

esto elimina duplicados en su lugar, sin hacer una nueva tabla

ALTER IGNORE TABLE `table_name` ADD UNIQUE (title, SID)

nota: solo funciona bien si el índice cabe en la memoria

usuario187291
fuente
26
Aviso: esto mantendría el registro duplicado más antiguo y borraría los más nuevos. Si desea conservar lo más nuevo, no puede hacer esto ALTER IGNORE.
Haralan Dobrev
9
No parece funcionar con InnoDB. Corrí ALTER TABLE foo ENGINE MyISAMpara evitarlo, volví a cambiar el motor.
Martin
13
esto podría fallar en MySQL> 5.5, si es así, use "set session old_alter_table = 1;" y "establecer sesión old_alter_table = 0;" antes y después de la declaración
chillitom
2
@delatbabel La razón para despreciarla se da en la página a la que ha vinculado
Barmar
133

Supongamos que tiene una tabla employee, con las siguientes columnas:

employee (first_name, last_name, start_date)

Para eliminar las filas con una first_namecolumna duplicada :

delete
from employee using employee,
    employee e1
where employee.id > e1.id
    and employee.first_name = e1.first_name  
Abhijoy_D
fuente
1
¿El registro restante tendrá la identificación máxima o mínima en su grupo de duplicación?
Frozen Flame
El registro restante tendrá la identificación mínima, ya que es el único que no cumple con la condición para ser eliminado
Pablo Guerrero
1
Parece que unirse employeecontra sí mismo para una coincidencia de índice y una >verificación en un índice será lenta para tablas grandes. ¿No sería mejor SELECT MAX(ID) FROM t GROUP BY uniquey luego JOINa una coincidencia exacta de IDa MAX(ID)?
ebyrob
1
¡Gran respuesta! Me salvó el tiempo!
Nesar
56

Después de eliminar duplicados para todos los SID-s, no solo uno solo.

Con mesa de temperatura

CREATE TABLE table_temp AS
SELECT * FROM table GROUP BY title, SID;

DROP TABLE table;
RENAME TABLE table_temp TO table;

Como temp_tableestá recién creado, no tiene índices. Deberá volver a crearlos después de eliminar los duplicados. Puede verificar qué índices tiene en la tabla conSHOW INDEXES IN table

Sin tabla temporal:

DELETE FROM `table` WHERE id IN (
  SELECT all_duplicates.id FROM (
    SELECT id FROM `table` WHERE (`title`, `SID`) IN (
      SELECT `title`, `SID` FROM `table` GROUP BY `title`, `SID` having count(*) > 1
    )
  ) AS all_duplicates 
  LEFT JOIN (
    SELECT id FROM `table` GROUP BY `title`, `SID` having count(*) > 1
  ) AS grouped_duplicates 
  ON all_duplicates.id = grouped_duplicates.id 
  WHERE grouped_duplicates.id IS NULL
)
Kamil Szot
fuente
44
GROUP-ing produce solo una fila de resultados para cada combinación de valores de campos por los que agrupa. Entonces los duplicados serán eliminados.
Kamil Szot
44
Me gusta la primera manera, demasiado elegante aquí! : B
AgelessEssence
1
@fiacre Puede deshabilitar temporalmente las comprobaciones de clave externa: stackoverflow.com/questions/15501673/… También podría arriesgarse a eliminar algunas de las filas a las que hacen referencia otras tablas, pero puede controlar qué registros se seleccionan en la tabla deducida alterando la consulta SELECT * FROM table GROUP BY title, SID;Todo depende de qué tan bien sepa lo que está haciendo.
Kamil Szot
1
@ahnbizcad Puede usar una tabla temporal pero luego tendrá que copiar los datos de la tabla temporal a la tabla normal. Si usa una tabla real, puede soltar la antigua con los duplicados y cambiar el nombre de la nueva, sin el duplicado al nombre del anterior.
Kamil Szot
1
El método "sin tabla temporal" está más cerca de la mejor solución, sin embargo ten cuidado con el manejo ONLY_FULL_GROUP_BY que cambió en MySQL 5.7.5: dev.mysql.com/doc/refman/5.7/en/group-by-handling.html Tengo este para trabajar reemplazando "SELECT id" por "SELECT ANY_VALUE (id) AS id"
delatbabel
53

Eliminar filas duplicadas en MySQL in situ, (suponiendo que tenga una columna de marca de tiempo para ordenar) tutorial:

Crea la tabla e inserta algunas filas:

create table penguins(foo int, bar varchar(15), baz datetime);
insert into penguins values(1, 'skipper', now());
insert into penguins values(1, 'skipper', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(4, 'rico', now());
select * from penguins;
    +------+----------+---------------------+
    | foo  | bar      | baz                 |
    +------+----------+---------------------+
    |    1 | skipper  | 2014-08-25 14:21:54 |
    |    1 | skipper  | 2014-08-25 14:21:59 |
    |    3 | kowalski | 2014-08-25 14:22:09 |
    |    3 | kowalski | 2014-08-25 14:22:13 |
    |    3 | kowalski | 2014-08-25 14:22:15 |
    |    4 | rico     | 2014-08-25 14:22:22 |
    +------+----------+---------------------+
6 rows in set (0.00 sec)

Eliminar los duplicados en su lugar:

delete a
    from penguins a
    left join(
    select max(baz) maxtimestamp, foo, bar
    from penguins
    group by foo, bar) b
    on a.baz = maxtimestamp and
    a.foo = b.foo and
    a.bar = b.bar
    where b.maxtimestamp IS NULL;
Query OK, 3 rows affected (0.01 sec)
select * from penguins;
+------+----------+---------------------+
| foo  | bar      | baz                 |
+------+----------+---------------------+
|    1 | skipper  | 2014-08-25 14:21:59 |
|    3 | kowalski | 2014-08-25 14:22:15 |
|    4 | rico     | 2014-08-25 14:22:22 |
+------+----------+---------------------+
3 rows in set (0.00 sec)

Ya ha terminado, se eliminan las filas duplicadas, se guarda la última por marca de tiempo.

Para aquellos de ustedes sin una marca de tiempo o una columna única.

¿No tiene una timestampo una columna de índice única para ordenar? Estás viviendo en un estado de degeneración. Tendrá que realizar pasos adicionales para eliminar filas duplicadas.

crea la tabla de pingüinos y agrega algunas filas

create table penguins(foo int, bar varchar(15)); 
insert into penguins values(1, 'skipper'); 
insert into penguins values(1, 'skipper'); 
insert into penguins values(3, 'kowalski'); 
insert into penguins values(3, 'kowalski'); 
insert into penguins values(3, 'kowalski'); 
insert into penguins values(4, 'rico'); 
select * from penguins; 
    # +------+----------+ 
    # | foo  | bar      | 
    # +------+----------+ 
    # |    1 | skipper  | 
    # |    1 | skipper  | 
    # |    3 | kowalski | 
    # |    3 | kowalski | 
    # |    3 | kowalski | 
    # |    4 | rico     | 
    # +------+----------+ 

haga un clon de la primera tabla y cópiela.

drop table if exists penguins_copy; 
create table penguins_copy as ( SELECT foo, bar FROM penguins );  

#add an autoincrementing primary key: 
ALTER TABLE penguins_copy ADD moo int AUTO_INCREMENT PRIMARY KEY first; 

select * from penguins_copy; 
    # +-----+------+----------+ 
    # | moo | foo  | bar      | 
    # +-----+------+----------+ 
    # |   1 |    1 | skipper  | 
    # |   2 |    1 | skipper  | 
    # |   3 |    3 | kowalski | 
    # |   4 |    3 | kowalski | 
    # |   5 |    3 | kowalski | 
    # |   6 |    4 | rico     | 
    # +-----+------+----------+ 

El agregado máximo opera sobre el nuevo índice moo:

delete a from penguins_copy a left join( 
    select max(moo) myindex, foo, bar 
    from penguins_copy 
    group by foo, bar) b 
    on a.moo = b.myindex and 
    a.foo = b.foo and 
    a.bar = b.bar 
    where b.myindex IS NULL; 

#drop the extra column on the copied table 
alter table penguins_copy drop moo; 
select * from penguins_copy; 

#drop the first table and put the copy table back: 
drop table penguins; 
create table penguins select * from penguins_copy; 

observar y limpiar

drop table penguins_copy; 
select * from penguins;
+------+----------+ 
| foo  | bar      | 
+------+----------+ 
|    1 | skipper  | 
|    3 | kowalski | 
|    4 | rico     | 
+------+----------+ 
    Elapsed: 1458.359 milliseconds 

¿Qué está haciendo esa gran declaración de eliminación de SQL?

Los pingüinos de mesa con el alias 'a' se unen en un subconjunto de pingüinos de mesa llamado alias 'b'. La tabla de la derecha 'b', que es un subconjunto, encuentra la marca de tiempo máxima [o max moo] agrupada por columnas foo y bar. Esto coincide con la tabla de la izquierda 'a'. (foo, bar, baz) a la izquierda tiene cada fila en la tabla. El subconjunto de la derecha 'b' tiene un (maxtimestamp, foo, bar) que coincide con el izquierdo solo en el que ES el máximo.

Cada fila que no es ese máximo tiene el valor maxtimestamp de NULL. Filtra hacia abajo en esas filas NULL y tienes un conjunto de todas las filas agrupadas por foo y bar que no es el último baz de marca de tiempo. Eliminar esos.

Haga una copia de seguridad de la tabla antes de ejecutar esto.

Evite que este problema vuelva a ocurrir en esta tabla:

Si conseguiste que esto funcione, y apagó tu fuego de "fila duplicada". Excelente. Ahora defina una nueva clave compuesta única en su tabla (en esas dos columnas) para evitar que se agreguen más duplicados en primer lugar.

Al igual que un buen sistema inmunitario, las filas malas ni siquiera deberían permitirse en la mesa en el momento de la inserción. Más tarde, todos los programas que agreguen duplicados transmitirán su protesta, y cuando los arregles, este problema nunca volverá a aparecer.

Eric Leschinski
fuente
66
¡califique solamente para la referencia de Madagascar!
Michael Wiggins
1
Calificado ya que esta es una gran respuesta y excelentes sugerencias, gracias Eric trabajó mejor que cualquier otra respuesta.
johan
44
Nota: Si su tabla tiene una IDcolumna de incremento automático , entonces la ONcláusula solo debe coincidir con la IDcolumna, nada más.
ebyrob
1
Me gusta la explicación detallada pero ... Si entiendo correctamente, esta respuesta hace uso de la marca de tiempo para distinguir entre registros. En ese sentido, los registros no están duplicados. ¿Qué sucede si no tuviera una marca de tiempo para distinguir entre registros, es decir, todas las columnas son iguales para 2 o más registros?
Rsc Rsc
1
@RscRsc Si no tiene una columna de marca de tiempo o un índice único para aplicar el agregado máximo, entonces parece que tiene que duplicar la tabla, agregar un índice único, aplicar la declaración de eliminación y luego sustituir la tabla copiada por el original . Cambié la respuesta para reflejar estas instrucciones.
Eric Leschinski, el
16

Después de encontrarme con este problema, en una gran base de datos, no estaba completamente impresionado con el rendimiento de ninguna de las otras respuestas. Quiero mantener solo la última fila duplicada y eliminar el resto.

En una declaración de una consulta, sin una tabla temporal, esto funcionó mejor para mí,

DELETE e.*
FROM employee e
WHERE id IN
 (SELECT id
   FROM (SELECT MIN(id) as id
          FROM employee e2
          GROUP BY first_name, last_name
          HAVING COUNT(*) > 1) x);

La única advertencia es que tengo que ejecutar la consulta varias veces, pero incluso con eso, encontré que funcionó mejor para mí que las otras opciones.

selladores
fuente
1
¡Solución pragmática! Funcionó para mí, unos 20 años para una mesa innodb de 2m + filas. Una vez que lo usé varias veces y me quedé con unos pocos delincuentes con un alto número de duplicados, terminé el trabajo manualmente.
Troy Wray
1
Me funcionó de una vez, ¡increíble!
Murwa
Debe ejecutarse varias veces si los duplicados para cualquier columna son más de 2
veces
@PayteR que se indica en la respuesta, "La única advertencia es que tengo que ejecutar la consulta varias veces"
Seaders
13

Esto siempre parece funcionar para mí:

CREATE TABLE NoDupeTable LIKE DupeTable; 
INSERT NoDupeTable SELECT * FROM DupeTable group by CommonField1,CommonFieldN;

Que mantiene la ID más baja en cada uno de los duplicados y el resto de los registros no duplicados.

También he hecho lo siguiente para que el problema de engaño ya no ocurra después de la eliminación:

CREATE TABLE NoDupeTable LIKE DupeTable; 
Alter table NoDupeTable Add Unique `Unique` (CommonField1,CommonField2);
INSERT IGNORE NoDupeTable SELECT * FROM DupeTable;

En otras palabras, creo un duplicado de la primera tabla, agrego un índice único en los campos de los que no quiero duplicados y luego hago uno Insert IGNOREque tiene la ventaja de no fallar como lo Insertharía normalmente la primera vez que intentó agregar un registro duplicado basado en los dos campos e ignora dichos registros.

Al mover fwd se hace imposible crear registros duplicados basados ​​en esos dos campos.

usuario3649739
fuente
1
¿No necesitarías un ORDER BYen el SELECTpara estar seguro de qué registro realmente pasa al NoDupeTable?
ebyrob
@ebyrob, creo que, a menos que se indique lo contrario, seleccionará la ID más baja en ausencia de otros criterios. Por supuesto ORDER by ID Asc, no podría doler, así que editaré mi respuesta de todos modos.
user3649739
@ebyrob Lo siento, mi mal. Ordenar por no funcionará en esta selección a mi entender. Un pedido por al final de la selección solo ordenará los duplicados encontrados por la ID más baja encontrada en cada par. Alternativamente, podría hacer ay Select Max(ID)luego, Order by Max(ID)pero todo lo que haría sería invertir el orden de la inserción. Para obtener la ID más alta requeriría Creo que una selección select más compleja ya que, independientemente de cómo ordene arriba, tomará los valores de campo de la ID más baja.
user3649739
En realidad, no estoy seguro de lo que estaba pensando en orden. Definitivamente querría MAX(ID)o MIN(ID)y nombres de columna en lugar de *en el SELECT FROM DupeTablede que, de lo contrario vas a tener uno de los ID's al azar. De hecho, muchos SQL e incluso MySQL estrictos requieren llamar a una función agregada en cada columna no especificada en la GROUP BYcláusula.
ebyrob
@ebyrob Al probar Max (ID) Min (ID) no haga nada excepto devolver la ID del registro Max o Mind. En cada caso agarra los mismos registros. Entonces, si tuviera dos registros con campos ID,First,Last,Notesy registros 1,Bob,Smith,NULLy 2,Bob,Smith,Arrearsluego hacer un SELECT *Max(ID), First,Last,Notes FROM DupeTable group by First,Last, ambos devolverían el mismo registro, 1, excepto con una ID diferente. Max (ID) volvería 2,Bob,Smith,NULLy Min (ID) volvería 1,Bob,Smith,NULL. Para obtener el segundo registro con 'Atrasos' en las notas se requiere una unión, creo.
user3649739
7

Lo siguiente funciona para todas las tablas

CREATE TABLE `noDup` LIKE `Dup` ;
INSERT `noDup` SELECT DISTINCT * FROM `Dup` ;
DROP TABLE `Dup` ;
ALTER TABLE `noDup` RENAME `Dup` ;
MBMiri
fuente
6

Aquí hay una respuesta simple:

delete a from target_table a left JOIN (select max(id_field) as id, field_being_repeated  
    from target_table GROUP BY field_being_repeated) b 
    on a.field_being_repeated = b.field_being_repeated
      and a.id_field = b.id_field
    where b.id_field is null;
Ted Celestin
fuente
Es una buena respuesta, excepto un pequeño errorand a.id_field = b.id
Vikrant Goel
El LEFT JOINto bsolo necesita comparar b.id= a.id_fieldsuponiendo que field_ides un ID de incremento automático único. entonces a.field_being_repeated = b.field_being_repeatedes extraño. ( b.id_fieldtampoco existe en esta consulta es b.id.
ebyrob
6

Este trabajo para mí para eliminar registros antiguos:

delete from table where id in 
(select min(e.id)
    from (select * from table) e 
    group by column1, column2
    having count(*) > 1
); 

Puede reemplazar min (e.id) a max (e.id) para eliminar los registros más recientes.

richardhell
fuente
5
delete p from 
product p
inner join (
    select max(id) as id, url from product 
    group by url 
    having count(*) > 1
) unik on unik.url = p.url and unik.id != p.id;
temonehm
fuente
1
Encontré una solución mucho más
eficaz
5

Creo que la solución de Werner anterior es la más conveniente porque funciona independientemente de la presencia de una clave principal, no se mete con las tablas, usa sql a prueba de futuro, es muy comprensible.

Como dije en mi comentario, esa solución no se ha explicado correctamente. Entonces esto es mío, basado en eso.

1) agregar una nueva columna booleana

alter table mytable add tokeep boolean;

2) agregue una restricción en las columnas duplicadas Y la nueva columna

alter table mytable add constraint preventdupe unique (mycol1, mycol2, tokeep);

3) establece la columna booleana en verdadero. Esto tendrá éxito solo en una de las filas duplicadas debido a la nueva restricción

update ignore mytable set tokeep = true;

4) eliminar filas que no se han marcado como mantenimiento

delete from mytable where tokeep is null;

5) suelte la columna agregada

alter table mytable drop tokeep;

Le sugiero que mantenga la restricción que agregó, para evitar nuevos duplicados en el futuro.

xtian
fuente
4

Este procedimiento eliminará todos los duplicados (incluidos los múltiplos) en una tabla, manteniendo el último duplicado. Esta es una extensión de Recuperar el último registro en cada grupo

Espero que sea útil para alguien.

DROP TABLE IF EXISTS UniqueIDs;
CREATE Temporary table UniqueIDs (id Int(11));

INSERT INTO UniqueIDs
    (SELECT T1.ID FROM Table T1 LEFT JOIN Table T2 ON
    (T1.Field1 = T2.Field1 AND T1.Field2 = T2.Field2 #Comparison Fields 
    AND T1.ID < T2.ID)
    WHERE T2.ID IS NULL);

DELETE FROM Table WHERE id NOT IN (SELECT ID FROM UniqueIDs);
Simón
fuente
4

Otra forma fácil ... usando ACTUALIZAR IGNORE:

U tiene que usar un índice en una o más columnas (tipo índice). Cree una nueva columna de referencia temporal (que no forme parte del índice). En esta columna, marca los exclusivos actualizándolos con la cláusula ignorar. Paso a paso:

Agregue una columna de referencia temporal para marcar los únicos:

ALTER TABLE `yourtable` ADD `unique` VARCHAR(3) NOT NULL AFTER `lastcolname`;

=> esto agregará una columna a su tabla.

Actualice la tabla, intente marcar todo como único, pero ignore los posibles errores debido a un problema clave duplicado (se omitirán los registros):

UPDATE IGNORE `yourtable` SET `unique` = 'Yes' WHERE 1;

=> encontrará que sus registros duplicados no se marcarán como únicos = 'Sí', en otras palabras, solo uno de cada conjunto de registros duplicados se marcará como único.

Elimina todo lo que no sea único:

DELETE * FROM `yourtable` WHERE `unique` <> 'Yes';

=> Esto eliminará todos los registros duplicados.

Suelta la columna ...

ALTER TABLE `yourtable` DROP `unique`;
Werner
fuente
Creo que esta es la mejor solución porque no se mete con las tablas y usa sql simple y simple. Una única cosa debe quedar clara: la uniquecolumna DEBE agregarse a una restricción única junto con las columnas que están duplicadas actualmente, de lo contrario, todo no funciona porque SET unique= 'Sí' nunca fallará.
xtian
También tenga en cuenta que uniquees una palabra clave mysql. Por lo tanto, debe tener los backticks (como ya se muestra correctamente). Usar otra palabra para la columna podría ser más conveniente.
Torsten
2

Eliminar duplicados en tablas MySQL es un problema común, que generalmente viene con necesidades específicas. En caso de que alguien esté interesado, aquí ( Eliminar filas duplicadas en MySQL ) explico cómo usar una tabla temporal para eliminar duplicados de MySQL de manera confiable y rápida, también válida para manejar grandes fuentes de datos (con ejemplos para diferentes casos de uso).

Ali , en tu caso, puedes ejecutar algo como esto:

-- create a new temporary table
CREATE TABLE tmp_table1 LIKE table1;

-- add a unique constraint    
ALTER TABLE tmp_table1 ADD UNIQUE(sid, title);

-- scan over the table to insert entries
INSERT IGNORE INTO tmp_table1 SELECT * FROM table1 ORDER BY sid;

-- rename tables
RENAME TABLE table1 TO backup_table1, tmp_table1 TO table1;
César Revert-Gomar
fuente
0
delete from `table` where `table`.`SID` in 
    (
    select t.SID from table t join table t1 on t.title = t1.title  where t.SID > t1.SID
)
Patricio
fuente
Esto genera un error de SQL (1093) en algunas configuraciones y versiones de MySQL.
ebyrob
0

Me encanta la respuesta de @ eric, pero parece que no funciona si tienes una mesa realmente grande (la obtengo The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okaycuando intento ejecutarla). Así que limité la consulta de combinación para considerar solo las filas duplicadas y terminé con:

DELETE a FROM penguins a
    LEFT JOIN (SELECT COUNT(baz) AS num, MIN(baz) AS keepBaz, foo
        FROM penguins
        GROUP BY deviceId HAVING num > 1) b
        ON a.baz != b.keepBaz
        AND a.foo = b.foo
    WHERE b.foo IS NOT NULL

La cláusula WHERE en este caso permite que MySQL ignore cualquier fila que no tenga un duplicado y también ignorará si esta es la primera instancia del duplicado, por lo que solo se ignorarán los duplicados posteriores. Cambie MIN(baz)a MAX(baz)para mantener la última instancia en lugar de la primera.

Gujamin
fuente
0

Esto funciona para tablas grandes:

 CREATE Temporary table duplicates AS select max(id) as id, url from links group by url having count(*) > 1;

 DELETE l from links l inner join duplicates ld on ld.id = l.id WHERE ld.id IS NOT NULL;

Para eliminar el cambio más antiguo max(id)amin(id)

Mugoma J. Okomba
fuente
0

Esto hará que la columna se convierta column_nameen una clave principal y, mientras tanto, ignore todos los errores. Por lo tanto, eliminará las filas con un valor duplicado para column_name.

ALTER IGNORE TABLE `table_name` ADD PRIMARY KEY (`column_name`);
Abraham Murciano Benzadon
fuente
Como se señaló en los comentarios a la respuesta anterior, esto ya no funciona en 5.7.
Barmar
0

Creo que esto funcionará básicamente copiando la tabla y vaciándola y luego volviendo a colocar solo los valores distintos, pero revísela antes de hacerlo en grandes cantidades de datos.

Crea una copia al carbón de tu mesa

crear tabla temp_table como oldtablename; inserte temp_table select * from oldtablename;

Vacía tu mesa original

DELETE * de oldtablename;

Copia todos los valores distintos de la tabla copiada a su tabla original

INSERTAR oldtablename SELECT * del grupo temp_table por nombre, apellido, dob

Elimina tu tabla temporal.

Drop Table temp_table

Necesita agrupar por todos los campos que desea mantener distintos.

ChrisAardvark
fuente
0
DELETE T2
FROM   table_name T1
JOIN   same_table_name T2 ON (T1.title = T2.title AND T1.ID <> T2.ID)
Nav
fuente
No funciona su solicitud, ¿podría mejorarla?
Samir Guiderk
0

así es como generalmente elimino los duplicados

  1. agregue una columna temporal, asígnele el nombre que desee (me referiré como activo)
  2. agrupe por los campos que cree que no deberían estar duplicados y establezca su activo en 1, agrupando por seleccionará solo uno de los valores duplicados (no seleccionará duplicados) para esas columnas
  3. eliminar los que tienen cero activo
  4. soltar columna activa
  5. opcionalmente (si se ajusta a sus propósitos), agregue un índice único para que esas columnas no vuelvan a tener duplicados
Yazgan
fuente
-2

Puede usar una cláusula DISTINCT para seleccionar la lista "limpiada" (y aquí hay un ejemplo muy sencillo sobre cómo hacerlo).

Rosamunda
fuente
¿Cómo responde eso a la pregunta? Al DISTINCTusarlo, pierde toda la información sobre duplicados que podría haber tenido en primer lugar. ¿Puedes mostrar una forma de eliminar duplicados usándolo?
luk2302
-3

¿Podría funcionar si los cuenta y luego agrega un límite a su consulta de eliminación dejando solo uno?

Por ejemplo, si tiene dos o más, escriba su consulta de esta manera:

DELETE FROM table WHERE SID = 1 LIMIT 1;
usuario3325657
fuente
-5

Solo hay unos pocos pasos básicos al eliminar datos duplicados de su tabla:

  • ¡Respalda tu mesa!
  • Encuentra las filas duplicadas
  • Eliminar las filas duplicadas

Aquí está el tutorial completo: https://blog.teamsql.io/deleting-duplicate-data-3541485b3473

Poder
fuente
¿Funciona si solo la identificación única es diferente? Eğer sadece benzersiz id farklı ise de bu işe yarar mı?
Andrew
Por defecto, el método descrito aquí no funciona para las versiones de MySQL> 5.7.5. Esto se debe al manejo de ONLY_FULL_GROUP_BY. Ver aquí: dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
delatbabel