Como excluir duplicatas em uma tabela MySQL?


158

Eu preciso de DELETElinhas duplicadas para sid especificado em uma MySQLtabela.

Como posso fazer isso com uma consulta SQL?

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

Algo assim, mas não sei como fazê-lo.


Você precisa fazer isso apenas uma vez ou precisa fazer isso o tempo todo?
Billy ONeal

Os registros com registros duplicados têm todos os mesmos dados ou o restante dos campos é diferente um do outro? Se você tiver a primeira opção, poderá simplesmente excluir todos os registros, exceto um, se tiver a segunda opção, como está determinando qual registro deseja manter?
rael_kid

@Lex Primeira opção. @ Billy eu preciso fazer isso o tempo todo.
23710 Ali Demirci

1
possível duplicado de Remover linhas duplicadas no MySQL
Basilevs

1
Há muitas coisas que mudaram aqui em várias versões do MySQL. Verifique sua versão do MySQL cuidadosamente antes de seguir o caminho de qualquer uma das soluções aqui.
Delatbabel 5/07

Respostas:


215

isso remove duplicatas no local, sem criar uma nova tabela

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

nota: só funciona bem se o índice couber na memória


26
Nota: isso manteria o registro duplicado mais antigo e apagaria os mais recentes. Se você deseja manter o mais novo, não pode fazê-lo ALTER IGNORE.
Haralan Dobrev 01/10/12

9
Não parece funcionar com o InnoDB. Corri ALTER TABLE foo ENGINE MyISAMpara contornar isso, troquei o motor depois.
277 Martin

13
isso pode falhar no MySQL> 5.5, se sim, use "set session old_alter_table = 1;" e "definir sessão old_alter_table = 0;" antes e depois da declaração
chillitom 26/09


2
@delatbabel O motivo para descontinuá-lo é dado na página que você vinculou.
Barmar

133

Suponha que você tenha uma tabela employeecom as seguintes colunas:

employee (first_name, last_name, start_date)

Para excluir as linhas com uma first_namecoluna duplicada :

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

1
O registro restante terá o ID máximo ou mínimo em seu grupo duplicado?
Frozen Flame

O registro restante terá a id mínimo, uma vez que é o único que não atender a condição de ser excluído
Pablo Guerrero

1
Parece unir- employeese a si próprio para uma correspondência de índice e uma >verificação em um índice será lenta para tabelas grandes. Não seria melhor SELECT MAX(ID) FROM t GROUP BY uniquee então JOINuma correspondência exata de IDpara MAX(ID)?
Ebyrob 10/11/16

1
Ótima resposta! Economizei meu tempo!
Nesar

56

A seguir, remova duplicatas para todos os SID-s, não apenas um.

Com tabela temporária

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

DROP TABLE table;
RENAME TABLE table_temp TO table;

Desde que temp_tablefoi criado recentemente, não possui índices. Você precisará recriá-los após remover as duplicatas. Você pode verificar quais índices você possui na tabela comSHOW INDEXES IN table

Sem tabela temporária:

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
GROUP-ing produz apenas uma linha de resultado para cada combinação de valores de campos pelos quais você agrupa. Portanto, duplicatas serão removidas.
Kamil Szot

4
eu gosto da primeira maneira, muito elegante aqui! : B
AgelessEssence

1
@fiacre Você pode desativar temporariamente as verificações de chave estrangeira: stackoverflow.com/questions/15501673/… Você também pode estar arriscando remover algumas das linhas às quais outras tabelas se referem, mas pode controlar quais registros são selecionados na tabela deduplicada alterando a consulta SELECT * FROM table GROUP BY title, SID;Tudo depende de quão bem você sabe o que está fazendo.
Kamil Szot

1
@ahnbizcad Você pode usar a tabela temporária, mas precisará copiar os dados de volta da tabela temporária para a tabela regular. Se você usar a tabela real, basta soltar a antiga com as duplicatas e renomear a nova, sem a duplicata para o nome da antiga.
precisa

1
O método "sem a tabela temp" está mais próximo da melhor solução no entanto cuidado com a manipulação ONLY_FULL_GROUP_BY que mudou no MySQL 5.7.5: dev.mysql.com/doc/refman/5.7/en/group-by-handling.html Eu tenho esse funcionar substituindo "SELECT id" por "SELECT ANY_VALUE (id) AS id"
delatbabel 5/17/17

53

Excluindo linhas duplicadas no MySQL no local, (Supondo que você tenha uma coluna de carimbo de data / hora para classificar por)

Crie a tabela e insira algumas linhas:

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)

Remova as duplicatas no 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)

Você terminou, as linhas duplicadas são removidas, a última por carimbo de data / hora é mantida.

Para aqueles sem carimbo de data / hora ou coluna exclusiva.

Você não tem uma timestampou uma coluna de índice exclusiva para classificar? Você está vivendo em um estado de degeneração. Você precisará executar etapas adicionais para excluir linhas duplicadas.

crie a tabela de pinguins e adicione algumas linhas

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

faça um clone da primeira tabela e copie para ela.

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

O agregado máximo opera com o novo í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 e limpar

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

O que essa grande instrução de exclusão SQL está fazendo?

Os pinguins de mesa com o pseudônimo 'a' são deixados unidos em um subconjunto de pinguins de mesa chamado pseudônimo 'b'. A tabela à direita 'b', que é um subconjunto, encontra o timestamp máximo [ou max moo] agrupado pelas colunas foo e bar. Isso corresponde à tabela da esquerda 'a'. (foo, bar, baz) à esquerda tem todas as linhas da tabela. O subconjunto direito 'b' possui um (carimbo de data e hora máx, foo, barra) que corresponde à esquerda apenas no que é o valor máx.

Cada linha que não seja esse max possui o valor maxtimestamp de NULL. Filtre essas linhas NULL e você terá um conjunto de todas as linhas agrupadas por foo e bar que não é o mais recente registro de data e hora. Exclua aqueles.

Faça um backup da tabela antes de executar isso.

Evite que esse problema aconteça novamente nesta tabela:

Se você conseguiu que isso funcionasse, e apagou o fogo da "linha duplicada". Ótimo. Agora defina uma nova chave exclusiva composta em sua tabela (nessas duas colunas) para impedir que mais duplicatas sejam adicionadas em primeiro lugar.

Como um bom sistema imunológico, as linhas defeituosas nem deveriam ser permitidas na tabela no momento da inserção. Posteriormente, todos os programas que adicionarem duplicados transmitirão seu protesto e, quando você os corrigir, esse problema nunca será exibido novamente.


6
Avalie-se puramente para a referência de Madagascar!
Michael Wiggins

1
Classificado como uma ótima resposta e ótimas sugestões, obrigado Eric trabalhou melhor do que qualquer outra resposta por aí.
johan

4
Nota: Se sua tabela tiver uma IDcoluna de incremento automático , a ONcláusula precisará apenas corresponder à IDcoluna, nada mais.
Ebyrob #

1
Gosto da explicação detalhada, mas ... Se entendi corretamente, esta resposta utiliza o carimbo de data e hora para distinguir entre registros. Nesse sentido, os registros não são duplicados. E se você não tivesse um carimbo de data / hora para distinguir entre registros, ou seja, todas as colunas são iguais para 2 ou mais registros?
Rsc Rsc

1
@RscRsc Se você não possui uma coluna de carimbo de data / hora ou índice exclusivo para aplicar o agregado máximo, parece que você deve duplicar a tabela, adicionar um índice exclusivo, aplicar a instrução delete e substituir a tabela copiada de volta ao original . Mudei a resposta para refletir essas instruções.
Eric Leschinski 9/11/19

16

Depois de me deparar com esse problema, em um grande banco de dados, não fiquei completamente impressionado com o desempenho de nenhuma das outras respostas. Quero manter apenas a última linha duplicada e excluir o restante.

Em uma declaração de uma consulta, sem uma tabela temporária, isso funcionou melhor para mim,

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

A única ressalva é que eu tenho que executar a consulta várias vezes, mas mesmo assim, achei que funcionou melhor para mim do que as outras opções.


1
Solução pragmática! Trabalhou para mim - cerca de 20 anos para uma mesa innodb 2m + row. Uma vez que o usei algumas vezes e reduzi alguns criminosos com alto número de duplicatas, concluí o trabalho manualmente.
Troy Wray

1
Trabalhou para mim em uma varredura, incrível!
Murwa

Ele deve ser executado várias vezes se as duplicatas de qualquer coluna tiverem mais de 2x
PayteR:

@PayteR que é referido na resposta: "A única ressalva é que eu tenho que correr as múltiplas consulta tempos"
seaders

13

Isso sempre parece funcionar para mim:

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

Que mantém o ID mais baixo em cada um dos enganos e no restante dos registros não fraudulentos.

Também fiz o seguinte para que o problema do dupe não ocorra mais após a remoção:

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

Em outras palavras, eu crio uma duplicata da primeira tabela, adiciono um índice exclusivo nos campos dos quais não quero duplicatas e, em seguida, faço um Insert IGNOREque tenha a vantagem de não falhar normalmente Insert, na primeira vez que tentasse adicionar um registro duplicado com base nos dois campos e ignora esses registros.

Movendo para a frente, torna-se impossível criar registros duplicados com base nesses dois campos.


1
Será que você não precisa de um ORDER BYno SELECTpara ter a certeza que registram realmente torna para o NoDupeTable?
Ebyrob 10/11/16

@ebyrob Eu acredito que, a menos que seja instruído de outra forma, ele selecionará o ID mais baixo na ausência de outros critérios. Claro que ORDER by ID Ascnão poderia machucar, então vou editar minha resposta.
user3649739

@ebyrob Desculpe meu mal. Ordenar por não funcionará nesta seleção, que eu saiba. Um Pedido no final da seleção solicitará apenas as duplicatas encontradas pelo ID mais baixo encontrado em cada par. Como alternativa, você pode fazer um Select Max(ID)e então, Order by Max(ID)mas tudo o que faria é inverter a ordem da inserção. Para obter o ID mais alto, seria necessária uma seleção mais complexa, pois, independentemente de como você solicitou acima, você estará obtendo os valores de campo do ID mais baixo.
user3649739

Na verdade, não tenho certeza do que eu estava pensando com a ordem. Você definitivamente quer MAX(ID)ou ou MIN(ID)nomes de colunas em vez de *no SELECT FROM DupeTableentanto, caso contrário, você apenas obterá um dos IDaleatoriamente. De fato, muitos SQLs e até mesmo o MySQL estrito requerem chamar uma função agregada em cada coluna não especificada na GROUP BYcláusula.
ebyrob

@ebyrob Ao testar o Max (ID) Min (ID), não faça nada, exceto retornar o ID do registro Max ou Mind. Em cada caso, pega os mesmos registros. Portanto, se eu tivesse dois registros com campos ID,First,Last,Notese registros 1,Bob,Smith,NULLe 2,Bob,Smith,Arrears, ao fazer um SELECT *Max(ID), First,Last,Notes FROM DupeTable group by First,Last, ambos retornariam o mesmo registro, 1, exceto com um ID diferente. Max (ID) retornaria 2,Bob,Smith,NULLe Min (ID) retornaria 1,Bob,Smith,NULL. Para obter o segundo registro com `Atrasados ​​'nas notas, é necessário juntar-me.
user3649739

7

O seguinte funciona para todas as tabelas

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

6

Aqui está uma resposta simples:

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;

Sua resposta uma boa, exceto um pequeno erroand a.id_field = b.id
Vikrant Goel

O LEFT JOINto bsó precisa comparar b.id= a.id_fieldassumindo que field_idé um ID de incremento automático exclusivo. assim a.field_being_repeated = b.field_being_repeatedé estranho. (também b.id_fieldnão existe nesta consulta b.id.
ebyrob 10/11/16

6

Este trabalho para remover os registros antigos:

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

Você pode substituir min (e.id) por max (e.id) para remover os registros mais recentes.


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
Eu descobri que uma solução muito mais
eficiente

5

Considero a solução de Werner acima a mais conveniente porque funciona independentemente da presença de uma chave primária, não mexe com tabelas, usa sql simples à prova de futuro, é muito compreensível.

Como afirmei no meu comentário, essa solução ainda não foi devidamente explicada. Então isso é meu, com base nisso.

1) adicione uma nova coluna booleana

alter table mytable add tokeep boolean;

2) adicione uma restrição nas colunas duplicadas E na nova coluna

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

3) defina a coluna booleana como true. Isso terá êxito apenas em uma das linhas duplicadas devido à nova restrição

update ignore mytable set tokeep = true;

4) excluir linhas que não foram marcadas como manutenção

delete from mytable where tokeep is null;

5) solte a coluna adicionada

alter table mytable drop tokeep;

Sugiro que você mantenha a restrição adicionada, para evitar novas duplicatas no futuro.


4

Este procedimento removerá todas as duplicatas (incluindo múltiplos) em uma tabela, mantendo a última duplicada. Esta é uma extensão de Recuperando o último registro em cada grupo

Espero que isso seja útil para alguém.

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

Outra maneira fácil ... usando UPDATE IGNORE:

Você tem que usar um índice em uma ou mais colunas (tipo índice). Crie uma nova coluna de referência temporária (não faça parte do índice). Nesta coluna, você marca os únicos, atualizando-o com a cláusula ignore. Passo a passo:

Adicione uma coluna de referência temporária para marcar os únicos:

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

=> isso adicionará uma coluna à sua tabela.

Atualize a tabela, tente marcar tudo como único, mas ignore os possíveis erros devido a um problema de chave duplicado (os registros serão ignorados):

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

=> você encontrará que seus registros duplicados não serão marcados como únicos = 'Sim'; em outras palavras, apenas um de cada conjunto de registros duplicados será marcado como exclusivo.

Exclua tudo o que não é exclusivo:

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

=> Isso removerá todos os registros duplicados.

Solte a coluna ...

ALTER TABLE `yourtable` DROP `unique`;

Eu acho que esta é a melhor solução, porque não mexe com tabelas e usa sql simples e simples. Uma única coisa deve ser esclarecida: a uniquecoluna DEVE ser adicionada a uma restrição exclusiva, juntamente com as colunas atualmente duplicadas; caso contrário, a coisa toda não funciona porque o SET unique= 'Yes' nunca falhará.
Xtian #

Lembre-se também de que uniqueé uma palavra-chave mysql. Portanto, ele precisa ter os backticks (como já exibidos corretamente). Usar outra palavra para a coluna pode ser mais conveniente.
Torsten

2

Excluir duplicatas em tabelas MySQL é um problema comum, que geralmente vem com necessidades específicas. Caso alguém esteja interessado, aqui ( Remover linhas duplicadas no MySQL ), explico como usar uma tabela temporária para excluir duplicatas do MySQL de maneira confiável e rápida, também válida para lidar com fontes de big data (com exemplos para diferentes casos de uso).

Ali , no seu caso, você pode executar algo como isto:

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

Isso gera o erro SQL (1093) em algumas configurações e versões do MySQL.
Ebyrob 10/11/16

0

A resposta de Love @ eric, mas não parece funcionar se você tiver uma mesa muito grande (estou recebendo 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 tento executá-la). Portanto, limitei a consulta de junção para considerar apenas as linhas duplicadas e acabei com:

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

A cláusula WHERE nesse caso permite que o MySQL ignore qualquer linha que não tenha uma duplicata e também ignorará se esta for a primeira instância da duplicata, portanto, apenas as duplicatas subsequentes serão ignoradas. Mude MIN(baz)para MAX(baz)para manter a última instância em vez da primeira.


0

Isso funciona para tabelas 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 excluir a alteração mais antiga max(id)paramin(id)


0

Isso aqui transformará a coluna column_nameem uma chave primária e, enquanto isso, ignorará todos os erros. Portanto, ele excluirá as linhas com um valor duplicado para column_name.

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

Conforme observado nos comentários da resposta anterior, isso não funciona mais na versão 5.7.
Barmar

0

Eu acho que isso funcionará basicamente copiando a tabela e esvaziando-a e colocando apenas os valores distintos novamente nela, mas verifique-a novamente antes de fazê-lo em grandes quantidades de dados.

Cria uma cópia carbono da sua tabela

crie a tabela temp_table como oldtablename; insira temp_table selecione * do nome da tabela antiga;

Esvazia sua tabela original

DELETE * do nome da tabela antiga;

Copia todos os valores distintos da tabela copiada de volta para a tabela original

INSERT oldtablename SELECT * do grupo temp_table por nome, sobrenome, dob

Exclui sua tabela temporária.

Soltar tabela temp_table

Você precisa agrupar por todos os campos que deseja manter distintos.


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

não atender à sua solicitação, você poderia melhorá-la?
Samir Guiderk

0

aqui está como eu costumo eliminar duplicatas

  1. adicione uma coluna temporária, atribua-lhe o nome que desejar (vou me referir como ativo)
  2. agrupar pelos campos que você acha que não devem ser duplicados e definir o ativo como 1, agrupando por selecionará apenas um dos valores duplicados (não selecionará duplicados) para essas colunas
  3. excluir aqueles com zero ativo
  4. soltar coluna ativa
  5. opcionalmente (se adequado aos seus objetivos), adicione um índice exclusivo para que essas colunas não tenham duplicatas novamente

-2

Você pode simplesmente usar uma cláusula DISTINCT para selecionar a lista "limpa" (e aqui está um exemplo muito fácil de como fazer isso).


Como isso responde à pergunta? Ao usar, DISTINCTvocê perde qualquer informação sobre duplicatas que possa ter recebido em primeiro lugar. Você pode mostrar uma maneira de excluir duplicatas usando-o?
Luk2302

-3

Poderia funcionar se você contá-los e adicionar um limite à sua consulta de exclusão deixando apenas um?

Por exemplo, se você tiver dois ou mais, escreva sua consulta assim:

DELETE FROM table WHERE SID = 1 LIMIT 1;

-5

Existem apenas algumas etapas básicas ao remover dados duplicados da sua tabela:

  • Faça backup da sua mesa!
  • Encontre as linhas duplicadas
  • Remova as linhas duplicadas

Aqui está o tutorial completo: https://blog.teamsql.io/deleting-duplicate-data-3541485b3473


Funciona se apenas o ID único for diferente. Qual é a Sadece benzersiz id farklı ise de bu işe yarar mı?
22417 Andrew Andrew

Por padrão, o método descrito aqui não funciona nas versões MySQL> 5.7.5. Isso ocorre devido ao manuseio de ONLY_FULL_GROUP_BY. Veja aqui: dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
delatbabel
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.