Come eliminare i duplicati su una tabella MySQL?


158

Devo DELETEduplicare le righe per il Sid specificato su una MySQLtabella.

Come posso farlo con una query SQL?

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

Qualcosa del genere, ma non so come farlo.


Hai bisogno di farlo solo una volta o devi farlo sempre?
Billy ONeal,

I record con i record duplicati hanno tutti gli stessi dati o il resto dei campi è diverso l'uno dall'altro? Se hai la prima opzione puoi semplicemente cancellare tutti i record tranne uno, se hai la seconda opzione, come stai determinando quale record vuoi conservare?
rael_kid,

@Lex Prima opzione. @Billy Devo farlo sempre.
Ali Demirci,

1
possibile duplicato di Rimuovi righe duplicate in MySQL
Basilevs

1
Ci sono molte cose che sono cambiate qui in varie versioni di MySQL. Controlla attentamente la tua versione di MySQL prima di saltare il percorso di una delle soluzioni qui.
delatbabel,

Risposte:


215

questo rimuove i duplicati sul posto, senza creare una nuova tabella

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

nota: funziona bene solo se l'indice si adatta alla memoria


26
Avviso: questo manterrebbe il record duplicato più vecchio e cancellerebbe quelli più recenti. Se vuoi mantenere il più recente non puoi farlo ALTER IGNORE.
Haralan Dobrev,

9
Non sembra funzionare con InnoDB. Corsi ALTER TABLE foo ENGINE MyISAMa aggirarlo, dopo aver cambiato motore.
Martin,

13
questo potrebbe non riuscire su MySQL> 5.5, in tal caso utilizzare "set session old_alter_table = 1;" e "imposta sessione old_alter_table = 0;" prima e dopo la dichiarazione
chillitom,


2
@delatbabel Il motivo del deprezzamento è indicato nella pagina a cui ti sei collegato.
Barmar,

133

Supponiamo di avere una tabella employee, con le seguenti colonne:

employee (first_name, last_name, start_date)

Per eliminare le righe con una first_namecolonna duplicata :

delete
from employee using employee,
    employee e1
where employee.id > e1.id
    and employee.first_name = e1.first_name  

1
Il record rimanente avrà l'id massimo o minimo nel suo gruppo di duplicazione?
Frozen Flame

Il record rimanente avrà l'id minimo poiché è l'unico che non soddisfa la condizione da eliminare
Pablo Guerrero,

1
Sembra unirsi employeecontro se stesso per una corrispondenza dell'indice e un >controllo su un indice sarà lento per le tabelle di grandi dimensioni. Non sarebbe meglio SELECT MAX(ID) FROM t GROUP BY uniquee poi JOINuna corrispondenza esatta di IDa MAX(ID)?
ebyrob dal

1
Bella risposta! Mi hai salvato il tempo!
Nesar,

56

In seguito rimuovi i duplicati per tutti i SID, non solo uno.

Con tavolo temporaneo

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

DROP TABLE table;
RENAME TABLE table_temp TO table;

Poiché temp_tableè stato appena creato, non ha indici. Dovrai ricrearli dopo aver rimosso i duplicati. Puoi controllare con quali indici hai la tabellaSHOW INDEXES IN table

Senza tabella temporanea:

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
)

4
Il raggruppamento produce solo una riga di risultati per ogni combinazione di valori di campi raggruppati. Quindi i duplicati verranno rimossi.
Kamil Szot,

4
mi piace il primo modo, troppo elegante qui! : B
AgelessEssence

1
@fiacre È possibile disabilitare temporaneamente i controlli delle chiavi esterne: stackoverflow.com/questions/15501673/… Potresti anche rischiare di rimuovere alcune delle righe a cui fanno riferimento altre tabelle, ma puoi controllare quali record vengono prelevati nella tabella dedotta modificando la query SELECT * FROM table GROUP BY title, SID;Tutto dipende da quanto bene sai cosa stai facendo.
Kamil Szot,

1
@ahnbizcad È possibile utilizzare la tabella temporanea, ma è necessario copiare nuovamente i dati dalla tabella temporanea alla tabella normale. Se usi la tabella reale puoi semplicemente rilasciare quella vecchia con i duplicati e rinominare quella nuova, senza duplicare il nome del vecchio.
Kamil Szot,

1
Il metodo "senza tabella temporanea" è il più vicino alla migliore soluzione, ma attenzione alla gestione ONLY_FULL_GROUP_BY che è cambiata in MySQL 5.7.5: dev.mysql.com/doc/refman/5.7/en/group-by-handling.html Ho capito per funzionare sostituendo "SELEZIONA ID" con "SELEZIONA ANY_VALUE (ID) COME ID"
delatbabel

53

Eliminazione di righe duplicate in MySQL sul posto, (supponendo che tu abbia un col timestamp per ordinare) procedura dettagliata:

Crea la tabella e inserisci alcune righe:

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)

Rimuovi i duplicati sul posto:

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)

Hai finito, le righe duplicate vengono rimosse, l'ultima per data e ora viene mantenuta.

Per quelli di voi senza un timestamp o una colonna unica.

Non hai una timestampo una colonna di indice unica per ordinare? Stai vivendo in uno stato di degenerazione. Dovrai eseguire ulteriori passaggi per eliminare le righe duplicate.

crea la tabella dei pinguini e aggiungi alcune righe

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     | 
    # +------+----------+ 

crea un clone della prima tabella e copialo al suo interno.

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     | 
    # +-----+------+----------+ 

L'aggregato massimo opera sul nuovo indice 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; 

osservare e pulire

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

Che cosa sta facendo quella grande dichiarazione di eliminazione SQL?

I pinguini di tabella con alias 'a' vengono lasciati uniti su un sottoinsieme di pinguini di tabella chiamato alias 'b'. La tabella di destra "b", che è un sottoinsieme, trova il timestamp massimo [o max moo] raggruppato per colonne foo e bar. Questo è abbinato alla tabella di sinistra "a". (foo, bar, baz) a sinistra ha tutte le righe nella tabella. Il sottoinsieme di destra "b" ha un (maxtimestamp, foo, bar) che è abbinato a sinistra solo su quello che è il max.

Ogni riga che non è quella massima ha valore maxtimestamp di NULL. Filtra verso il basso su quelle righe NULL e avrai un insieme di tutte le righe raggruppate per foo e bar che non è l'ultimo timestamp baz. Elimina quelli.

Eseguire un backup della tabella prima di eseguire questo.

Impedisci che questo problema si ripeta in questa tabella:

Se riesci a far funzionare tutto questo, spegni il fuoco "fila doppia". Grande. Ora definisci una nuova chiave univoca composita sulla tua tabella (su quelle due colonne) per evitare che vengano aggiunti più duplicati.

Come un buon sistema immunitario, le righe errate non dovrebbero nemmeno essere consentite nella tabella al momento dell'inserimento. Successivamente tutti quei programmi che aggiungono duplicati trasmetteranno la loro protesta e quando li risolvi, questo problema non si ripresenta più.


6
valutare puramente per il riferimento del Madagascar!
Michael Wiggins,

1
Valutato in quanto questa è un'ottima risposta e ottimi suggerimenti, grazie Eric ha lavorato meglio di qualsiasi altra risposta là fuori.
Giovanni il

4
Nota: se la tabella ha una IDcolonna di incremento automatico , la ONclausola deve corrispondere solo alla IDcolonna, nient'altro.
ebyrob dal

1
Mi piace la spiegazione dettagliata ma ... Se ho capito bene, questa risposta usa il timestamp per distinguere tra i record. In tal senso, i record non sono duplicati. E se non avessi il timestamp per distinguere tra i record, cioè tutti i col sono uguali per 2 o più record?
Rsc Rsc

1
@RscRsc Se non si dispone di una colonna timestamp o di un indice univoco a cui applicare l'aggregato massimo, sembra che sia necessario duplicare la tabella, aggiungere un indice univoco, applicare l'istruzione delete, quindi sostituire la tabella copiata con l'originale . Ho modificato la risposta per riflettere queste istruzioni.
Eric Leschinski,

16

Dopo essermi imbattuto in questo problema, su un enorme database, non sono stato completamente colpito dalle prestazioni di nessuna delle altre risposte. Voglio mantenere solo l'ultima riga duplicata ed eliminare il resto.

In un'istruzione a una query, senza una tabella temporanea, questo ha funzionato meglio per me,

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);

L'unica avvertenza è che devo eseguire la query più volte, ma nonostante ciò, ho scoperto che ha funzionato meglio per me rispetto alle altre opzioni.


1
Soluzione pragmatica! Ha funzionato per me - circa 20 anni per una tabella innodb 2m + riga. Una volta l'ho usato un paio di volte ed ero sceso a pochi trasgressori con un alto numero di duplicati, ho finito il lavoro manualmente.
Troy Wray,

1
Ha funzionato per me in un colpo solo, fantastico!
Murwa,

Deve essere eseguito più volte se i duplicati per qualsiasi colonna sono più di 2x
PayteR

@PayteR che è indicato nella risposta, "L'unica avvertenza è che devo eseguire la query più volte"
Seaders,

13

Questo sembra funzionare sempre per me:

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

Il che mantiene l'ID più basso su ciascuno dei duplicati e il resto dei record non duplicati.

Ho anche intrapreso le seguenti operazioni in modo che il problema dupe non si verifichi più dopo la rimozione:

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

In altre parole, creo un duplicato della prima tabella, aggiungo un indice univoco sui campi di cui non voglio duplicati, e quindi faccio uno Insert IGNOREche ha il vantaggio di non fallire normalmente come Insertla prima volta che provasse ad aggiungere un record duplicato basato sui due campi e ignora piuttosto tali record.

Spostando avanti diventa impossibile creare record duplicati basati su questi due campi.


1
Non avresti bisogno di un ORDER BYin SELECTper essere sicuro di quale disco effettivamente arriva al NoDupeTable?
ebyrob dal

@ebyrob Credo che, se non diversamente indicato, selezionerà l'ID più basso in assenza di altri criteri. Ovviamente ORDER by ID Ascnon poteva far male, quindi modificherò la mia risposta.
user3649739

@ebyrob Mi dispiace mio male. Ordina per non funzionerà in questa selezione per quanto ne sappia. Un ordine alla fine della selezione ordina solo i duplicati trovati dall'ID più basso trovato in ciascuna coppia. In alternativa potresti fare un Select Max(ID)e poi Order by Max(ID)ma tutto ciò che farebbe è invertire l'ordine dell'inserto. Per ottenere l'ID più alto richiederei credo che un join più complesso selezioni come, indipendentemente da come ordini sopra, afferrerai i valori del campo dall'ID inferiore.
user3649739

In realtà, non sono sicuro di cosa stavo pensando con ordine. Avresti sicuramente bisogno MAX(ID)o MIN(ID)nomi di colonne invece che *nel SELECT FROM DupeTablepensiero, altrimenti ne otterrai uno solo a IDcaso. In effetti, molti SQL e persino MySQL rigorosi richiedono di chiamare una funzione aggregata su ogni colonna non specificata nella GROUP BYclausola.
ebyrob,

@ebyrob Durante il test del Max (ID) Min (ID) non fare altro che restituire l'ID del record Max o Mind. In ogni caso prende gli stessi record. Quindi, se avessi due record con campi ID,First,Last,Notese record 1,Bob,Smith,NULLe 2,Bob,Smith,Arrearspoi facendo un SELECT *Max(ID), First,Last,Notes FROM DupeTable group by First,Last, entrambi restituirebbero lo stesso record, 1, tranne con un ID diverso. Max (ID) sarebbe tornato 2,Bob,Smith,NULLe Min (ID) sarebbe tornato 1,Bob,Smith,NULL. Per ottenere il secondo disco con "Arrears" nelle note è necessario un join credo.
user3649739

7

Quanto segue funziona per tutte le tabelle

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

6

Ecco una semplice risposta:

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;

È una buona risposta, tranne un piccolo erroreand a.id_field = b.id
Vikrant Goel,

Il LEFT JOINto bdeve solo confrontare b.id= a.id_fieldassumendo che field_idsia un ID di incremento automatico univoco. così a.field_being_repeated = b.field_being_repeatedè estraneo. (Anche b.id_fieldin questa query non esiste b.id.
ebyrob

6

Questo lavoro per me per rimuovere vecchi record:

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

È possibile sostituire min (e.id) a max (e.id) per rimuovere i record più recenti.


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;

1
Ho trovato che una soluzione molto più performante di quelle sopra
Christian Butzke il

5

Trovo che la soluzione di Werner sopra sia la più conveniente perché funziona indipendentemente dalla presenza di una chiave primaria, non scherza con le tabelle, usa sql a prova di futuro, è molto comprensibile.

Come ho affermato nel mio commento, questa soluzione non è stata spiegata correttamente però. Quindi questo è mio, basato su di esso.

1) aggiungi una nuova colonna booleana

alter table mytable add tokeep boolean;

2) aggiungere un vincolo alle colonne duplicate E alla nuova colonna

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

3) imposta la colonna booleana su true. Ciò avrà esito positivo solo su una delle righe duplicate a causa del nuovo vincolo

update ignore mytable set tokeep = true;

4) eliminare le righe che non sono state contrassegnate come mantenimento

delete from mytable where tokeep is null;

5) rilasciare la colonna aggiunta

alter table mytable drop tokeep;

Ti suggerisco di mantenere il vincolo che hai aggiunto, in modo da evitare nuovi duplicati in futuro.


4

Questa procedura rimuoverà tutti i duplicati (incl. Multipli) in una tabella, mantenendo l'ultimo duplicato. Questa è un'estensione del Recupero dell'ultimo record in ciascun gruppo

Spero che questo sia utile a qualcuno.

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);

4

Un altro modo semplice ... utilizzando UPDATE IGNORE:

Devi usare un indice su una o più colonne (digita indice). Crea una nuova colonna di riferimento temporaneo (non parte dell'indice). In questa colonna, contrassegni gli unici aggiornandoli con la clausola ignore. Passo dopo passo:

Aggiungi una colonna di riferimento temporanea per contrassegnare le uniche:

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

=> questo aggiungerà una colonna alla tua tabella.

Aggiorna la tabella, prova a contrassegnare tutto come univoco, ma ignora i possibili errori dovuti a problemi di chiave duplicati (i record verranno ignorati):

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

=> troverai che i tuoi record duplicati non saranno contrassegnati come unici = 'Sì', in altre parole solo uno di ogni set di record duplicati sarà contrassegnato come unico.

Elimina tutto ciò che non è unico:

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

=> Questo rimuoverà tutti i record duplicati.

Rilascia la colonna ...

ALTER TABLE `yourtable` DROP `unique`;

Penso che questa sia la soluzione migliore perché non si scherza con le tabelle e usa un semplice sql. Un'unica cosa dovrebbe essere chiarita: la uniquecolonna DEVE essere aggiunta a un vincolo univoco insieme alle colonne che sono attualmente duplicate, altrimenti l'intera cosa non funziona perché SET unique= 'Sì' non fallirebbe mai.
xtian

Inoltre, tieni presente che uniqueè una parola chiave mysql. Quindi deve avere i backtick (come già correttamente visualizzato). L'uso di un'altra parola per la colonna potrebbe essere più conveniente.
Torsten,

2

L'eliminazione dei duplicati sulle tabelle MySQL è un problema comune, che di solito comporta esigenze specifiche. Nel caso qualcuno fosse interessato, qui ( Rimuovi le righe duplicate in MySQL ) spiego come utilizzare una tabella temporanea per eliminare i duplicati MySQL in modo affidabile e veloce, valido anche per gestire le origini di big data (con esempi per diversi casi d'uso).

Ali , nel tuo caso, puoi eseguire qualcosa del genere:

-- 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;

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
)

Questo genera un errore SQL (1093) su alcune configurazioni e versioni di MySQL.
ebyrob il

0

La risposta di Love @ eric, ma non sembra funzionare se hai un tavolo davvero grande (lo ottengo 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 okayquando provo a eseguirlo). Quindi ho limitato la query di join a considerare solo le righe duplicate e ho finito 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 clausola WHERE in questo caso consente a MySQL di ignorare qualsiasi riga che non ha un duplicato e ignorerà anche se questa è la prima istanza del duplicato, quindi verranno ignorati solo i duplicati successivi. Passare MIN(baz)a MAX(baz)per mantenere l'ultima istanza anziché la prima.


0

Questo funziona per tavoli di grandi dimensioni:

 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;

Per eliminare le modifiche meno recenti max(id)amin(id)


0

Questo qui trasformerà la colonna column_namein una chiave primaria e nel frattempo ignorerà tutti gli errori. Quindi eliminerà le righe con un valore duplicato per column_name.

ALTER IGNORE TABLE `table_name` ADD PRIMARY KEY (`column_name`);

Come notato nei commenti alla risposta precedente, questo non funziona più in 5.7.
Barmar,

0

Penso che funzionerà fondamentalmente copiando la tabella e svuotandola, quindi reinserendo solo i valori distinti, ma per favore ricontrolla prima di farlo su grandi quantità di dati.

Crea una copia carbone della tua tabella

crea una tabella temp_table come oldtablename; inserisci temp_table seleziona * da oldtablename;

Svuota la tua tabella originale

ELIMINA * da oldtablename;

Copia tutti i valori distinti dalla tabella copiata alla tabella originale

INSERISCI oldtablename SELEZIONA * dal gruppo temp_table per nome, cognome, dob

Elimina la tabella temporanea.

Elimina tabella temp_table

È necessario raggruppare in base a TUTTI i campi che si desidera mantenere distinti.


0
DELETE T2
FROM   table_name T1
JOIN   same_table_name T2 ON (T1.title = T2.title AND T1.ID <> T2.ID)

non funziona la tua richiesta, per favore potresti migliorarla?
Samir Guiderk il

0

ecco come di solito elimino i duplicati

  1. aggiungi una colonna temporanea, chiamala come preferisci (mi riferirò come attiva)
  2. raggruppa per i campi che ritieni non debbano essere duplicati e imposta il loro attivo su 1, raggruppando selezionerà solo uno dei valori duplicati (non selezionerà i duplicati) per quelle colonne
  3. cancella quelli con zero attivo
  4. rilasciare la colonna attiva
  5. facoltativamente (se adatto ai tuoi scopi), aggiungi un indice univoco per quelle colonne per non avere più duplicati

-2

Potresti semplicemente usare una clausola DISTINCT per selezionare l'elenco "ripulito" (ed ecco un esempio molto semplice su come farlo).


Come risponde alla domanda? Usandoti DISTINCTperdi qualsiasi informazione sui duplicati che potresti avere avuto in primo luogo. Puoi mostrare un modo per eliminare i duplicati utilizzandolo?
luk2302,

-3

Potrebbe funzionare se li conti, quindi aggiungi un limite alla tua query di eliminazione lasciandone solo uno?

Ad esempio, se ne hai due o più, scrivi la tua query in questo modo:

DELETE FROM table WHERE SID = 1 LIMIT 1;

-5

Ci sono solo alcuni passaggi di base per la rimozione di dati duplicati dalla tabella:

  • Esegui il backup del tuo tavolo!
  • Trova le righe duplicate
  • Rimuovi le righe duplicate

Ecco il tutorial completo: https://blog.teamsql.io/deleting-duplicate-data-3541485b3473


Funziona se solo un ID unico è diverso. E 'triste Saddle Benzersiz id farklı ise de bu işe yarar mı?
Andrew,

Per impostazione predefinita, il metodo descritto qui non funziona per le versioni di MySQL> 5.7.5. Ciò è dovuto alla gestione di ONLY_FULL_GROUP_BY. Vedi qui: dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
delatbabel
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.