Eu preciso de DELETE
linhas duplicadas para sid especificado em uma MySQL
tabela.
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.
mysql
duplicates
Ali Demirci
fonte
fonte
Respostas:
isso remove duplicatas no local, sem criar uma nova tabela
nota: só funciona bem se o índice couber na memória
fonte
ALTER IGNORE
.ALTER TABLE foo ENGINE MyISAM
para contornar isso, troquei o motor depois.Suponha que você tenha uma tabela
employee
com as seguintes colunas:Para excluir as linhas com uma
first_name
coluna duplicada :fonte
employee
se 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 melhorSELECT MAX(ID) FROM t GROUP BY unique
e entãoJOIN
uma correspondência exata deID
paraMAX(ID)
?A seguir, remova duplicatas para todos os SID-s, não apenas um.
Com tabela temporária
Desde que
temp_table
foi 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:
fonte
SELECT * FROM table GROUP BY title, SID;
Tudo depende de quão bem você sabe o que está fazendo.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:
Remova as duplicatas no lugar:
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
timestamp
ou 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
faça um clone da primeira tabela e copie para ela.
O agregado máximo opera com o novo índice moo:
observar e limpar
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.
fonte
ID
coluna de incremento automático , aON
cláusula precisará apenas corresponder àID
coluna, nada mais.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,
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.
fonte
Isso sempre parece funcionar para mim:
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:
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 IGNORE
que tenha a vantagem de não falhar normalmenteInsert
, 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.
fonte
ORDER BY
noSELECT
para ter a certeza que registram realmente torna para oNoDupeTable
?ORDER by ID Asc
não poderia machucar, então vou editar minha resposta.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.MAX(ID)
ou ouMIN(ID)
nomes de colunas em vez de*
noSELECT FROM DupeTable
entanto, caso contrário, você apenas obterá um dosID
aleatoriamente. De fato, muitos SQLs e até mesmo o MySQL estrito requerem chamar uma função agregada em cada coluna não especificada naGROUP BY
cláusula.ID,First,Last,Notes
e registros1,Bob,Smith,NULL
e2,Bob,Smith,Arrears
, ao fazer umSELECT *Max(ID), First,Last,Notes FROM DupeTable group by First,Last
, ambos retornariam o mesmo registro, 1, exceto com um ID diferente. Max (ID) retornaria2,Bob,Smith,NULL
e Min (ID) retornaria1,Bob,Smith,NULL
. Para obter o segundo registro com `Atrasados 'nas notas, é necessário juntar-me.O seguinte funciona para todas as tabelas
fonte
Aqui está uma resposta simples:
fonte
and a.id_field = b.id
LEFT JOIN
tob
só precisa compararb.id
=a.id_field
assumindo quefield_id
é um ID de incremento automático exclusivo. assima.field_being_repeated = b.field_being_repeated
é estranho. (tambémb.id_field
não existe nesta consultab.id
.Este trabalho para remover os registros antigos:
Você pode substituir min (e.id) por max (e.id) para remover os registros mais recentes.
fonte
fonte
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
2) adicione uma restrição nas colunas duplicadas E na nova coluna
3) defina a coluna booleana como true. Isso terá êxito apenas em uma das linhas duplicadas devido à nova restrição
4) excluir linhas que não foram marcadas como manutenção
5) solte a coluna adicionada
Sugiro que você mantenha a restrição adicionada, para evitar novas duplicatas no futuro.
fonte
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.
fonte
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:
=> 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):
=> 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:
=> Isso removerá todos os registros duplicados.
Solte a coluna ...
fonte
unique
coluna 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 SETunique
= 'Yes' nunca falhará.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.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:
fonte
fonte
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 okay
quando tento executá-la). Portanto, limitei a consulta de junção para considerar apenas as linhas duplicadas e acabei com: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)
paraMAX(baz)
para manter a última instância em vez da primeira.fonte
Isso funciona para tabelas grandes:
Para excluir a alteração mais antiga
max(id)
paramin(id)
fonte
Isso aqui transformará a coluna
column_name
em uma chave primária e, enquanto isso, ignorará todos os erros. Portanto, ele excluirá as linhas com um valor duplicado paracolumn_name
.fonte
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
Esvazia sua tabela original
Copia todos os valores distintos da tabela copiada de volta para a tabela original
Exclui sua tabela temporária.
Você precisa agrupar por todos os campos que deseja manter distintos.
fonte
fonte
aqui está como eu costumo eliminar duplicatas
fonte
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).
fonte
DISTINCT
você perde qualquer informação sobre duplicatas que possa ter recebido em primeiro lugar. Você pode mostrar uma maneira de excluir duplicatas usando-o?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:
fonte
Existem apenas algumas etapas básicas ao remover dados duplicados da sua tabela:
Aqui está o tutorial completo: https://blog.teamsql.io/deleting-duplicate-data-3541485b3473
fonte