Eu tenho uma tabela com os seguintes campos:
id (Unique)
url (Unique)
title
company
site_id
Agora, preciso remover as linhas que possuem o mesmo title, company and site_id
. Uma maneira de fazer isso é usar o seguinte SQL junto com um script ( PHP
):
SELECT title, site_id, location, id, count( * )
FROM jobs
GROUP BY site_id, company, title, location
HAVING count( * ) >1
Depois de executar esta consulta, posso remover duplicatas usando um script do lado do servidor.
Mas quero saber se isso pode ser feito apenas usando a consulta SQL.
mysql
sql
duplicates
Chetan
fonte
fonte
Respostas:
Uma maneira realmente fácil de fazer isso é adicionar um
UNIQUE
índice nas 3 colunas. Ao escrever aALTER
declaração, inclua aIGNORE
palavra - chave Igual a:Isso eliminará todas as linhas duplicadas. Como um benefício adicional, o futuro
INSERTs
duplicado terá erros. Como sempre, convém fazer um backup antes de executar algo assim ...fonte
set session old_alter_table=1;
Se você não deseja alterar as propriedades da coluna, use a consulta abaixo.
Como você possui uma coluna que possui IDs exclusivos (por exemplo,
auto_increment
colunas), é possível usá-la para remover as duplicatas:No MySQL, você pode simplificá-lo ainda mais com o operador igual a segurança NULL (também conhecido como "operador de nave espacial" ):
fonte
O MySQL tem restrições sobre a referência à tabela da qual você está excluindo. Você pode contornar isso com uma tabela temporária, como:
Da sugestão de Kostanos nos comentários:
A única consulta lenta acima é DELETE, nos casos em que você possui um banco de dados muito grande. Esta consulta pode ser mais rápida:
fonte
DELETE FROM YourTable USING YourTable, tmpTable WHERE YourTable.id=tmpTable.id
DELETE
, mas tambémINSERT
para a mesa temporária, demorei muito tempo. Portanto, um índice para a tabela tmp poderia ajudar muitocreate index tmpTable_id_index on tmpTable (id)
, pelo menos para mim.create temporary table tmpTable (id int, PRIMARY KEY (id));
Se a
IGNORE
declaração não funcionar como no meu caso, você pode usar a declaração abaixo:fonte
A exclusão de duplicatas nas tabelas MySQL é um problema comum, geralmente o resultado de uma restrição ausente para evitar essas duplicatas com antecedência. Mas esse problema comum geralmente vem com necessidades específicas ... que exigem abordagens específicas. A abordagem deve ser diferente, dependendo, por exemplo, do tamanho dos dados, da entrada duplicada que deve ser mantida (geralmente a primeira ou a última), se existem índices a serem mantidos ou se queremos executar qualquer ação adicional. ação nos dados duplicados.
Também existem algumas especificidades no próprio MySQL, como não poder referenciar a mesma tabela em uma causa FROM ao executar uma tabela UPDATE (isso gerará o erro do MySQL # 1093). Essa limitação pode ser superada usando uma consulta interna com uma tabela temporária (conforme sugerido em algumas abordagens acima). Mas essa consulta interna não terá um desempenho especialmente bom ao lidar com fontes de big data.
No entanto, existe uma abordagem melhor para remover duplicatas, eficiente e confiável, e que pode ser facilmente adaptada a diferentes necessidades.
A idéia geral é criar uma nova tabela temporária, geralmente adicionando uma restrição exclusiva para evitar duplicatas adicionais e INSERIR os dados da tabela anterior na nova, enquanto cuida das duplicatas. Essa abordagem baseia-se em consultas simples do MySQL INSERT, cria uma nova restrição para evitar duplicatas adicionais e ignora a necessidade de usar uma consulta interna para procurar duplicatas e uma tabela temporária que deve ser mantida na memória (ajustando também fontes de big data).
É assim que isso pode ser alcançado. Dado que temos um funcionário da tabela , com as seguintes colunas:
Para excluir as linhas com uma coluna ssn duplicada e mantendo apenas a primeira entrada encontrada, o seguinte processo pode ser seguido:
Explicação técnica
⇒ Usando essa abordagem, 1,6 milhões de registros foram convertidos em 6k em menos de 200s.
Chetan , seguindo esse processo, você pode remover rápida e facilmente todas as suas duplicatas e criar uma restrição ÚNICA executando:
Obviamente, esse processo pode ser modificado ainda mais para adaptá-lo a diferentes necessidades ao excluir duplicatas. Alguns exemplos a seguir.
✔ Variação para manter a última entrada em vez da primeira
Às vezes, precisamos manter a última entrada duplicada em vez da primeira.
✔ Variação para executar algumas tarefas nas duplicatas, por exemplo, mantendo uma contagem nas duplicatas encontradas
Às vezes, precisamos executar algum processamento adicional nas entradas duplicadas encontradas (como manter uma contagem das duplicatas).
✔ Variação para regenerar o ID do campo auto-incremental
Às vezes, usamos um campo de incremento automático e, para manter o índice o mais compacto possível, podemos aproveitar a exclusão das duplicatas para gerar novamente o campo de incremento automático na nova tabela temporária.
✔ Outras variações
Muitas modificações adicionais também são possíveis, dependendo do comportamento desejado. Como exemplo, as consultas a seguir usarão uma segunda tabela temporária para, além de 1) manter a última entrada em vez da primeira; e 2) aumentar um contador nas duplicatas encontradas; também 3) regenere o ID do campo auto-incremental, mantendo a ordem de entrada como estava nos dados anteriores.
fonte
Existe outra solução:
fonte
se você tiver uma tabela grande com um grande número de registros, as soluções acima não funcionarão ou levarão muito tempo. Então nós temos uma solução diferente
fonte
Eu tenho esse snipet de consulta para SQLServer, mas acho que ele pode ser usado em outros DBMS com pequenas alterações:
Esqueci de lhe dizer que esta consulta não remove a linha com o ID mais baixo das linhas duplicadas. Se isso funcionar para você, tente esta consulta:
fonte
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..."
erro, use: oDELETE FROM Table WHERE Table.idTable IN ( SELECT MAX(idTable) FROM (SELECT * FROM idTable) AS tmp GROUP BY field1, field2, field3 HAVING COUNT(*) > 1)
que força o MySQL a criar uma tabela temporalmente. No entanto, é muito lento em grandes conjuntos de dados ... nesses casos, vou recomendar o código do Andomar, que é muito mais rápido.A maneira mais rápida é inserir linhas distintas em uma tabela temporária. Usando delete, levei algumas horas para remover duplicatas de uma tabela de 8 milhões de linhas. Usando insert e distinto, levou apenas 13 minutos.
fonte
TRUNCATE TABLE tableName
e 5ª linha deve dizerINSERT INTO tableName SELECT * FROM tempTableName;
Uma solução que é simples de entender e funciona sem chave primária:
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
Excluir linhas duplicadas usando a instrução DELETE JOIN O MySQL fornece a instrução DELETE JOIN que você pode usar para remover rapidamente linhas duplicadas.
A instrução a seguir exclui linhas duplicadas e mantém o ID mais alto:
fonte
Eu encontrei uma maneira simples. (mantenha o mais recente)
fonte
Simples e rápido para todos os casos:
fonte
Isso excluirá as linhas duplicadas com os mesmos valores para título, empresa e site. A primeira ocorrência será mantida e o restante de todas as duplicatas serão excluídas
fonte
Eu continuo visitando esta página sempre que eu google "remover duplicados do formulário mysql", mas para minhas soluções theIGNORE não funcionam porque eu tenho uma tabela mysql do InnoDB
esse código funciona melhor a qualquer momento
tableToclean = o nome da tabela que você precisa limpar
tableToclean_temp = uma tabela temporária criada e excluída
fonte
Essa solução moverá as duplicatas para uma tabela e os únicos para outra .
fonte
SELECT * FROM jobs GROUP BY site_id, company, title, location
?A partir da versão 8.0 (2018), o MySQL finalmente suporta funções de janela .
As funções da janela são práticas e eficientes. Aqui está uma solução que demonstra como usá-los para resolver essa tarefa.
Em uma subconsulta, podemos usar
ROW_NUMBER()
para atribuir uma posição a cada registro na tabela dentro decolumn1/column2
grupos, ordenados porid
. Se não houver duplicatas, o registro obterá o número da linha1
. Se existir duplicado, eles serão numerados por ascensãoid
(começando em1
).Depois que os registros são numerados corretamente na subconsulta, a consulta externa exclui todos os registros cujo número da linha não é 1.
Inquerir :
fonte
Para excluir o registro duplicado em uma tabela.
ou
fonte
fonte
Para duplicar registros com colunas exclusivas, por exemplo, COL1, COL2, COL3 não devem ser replicados (suponha que tenhamos perdido três colunas exclusivas na estrutura da tabela e que várias entradas duplicadas tenham sido feitas na tabela)
A esperança ajudará o desenvolvedor.
fonte
TL; TR;
Um tutorial muito descrito para solucionar esse problema pode ser encontrado no site mysqltutorial.org :
Como excluir linhas duplicadas no MySQL
É mostrado claramente como excluir linhas duplicadas de três maneiras diferentes :
A) Usando
DELETE JOIN
declaraçãoB) Usando uma tabela intermediária
C) Usando a
ROW_NUMBER()
funçãoEspero que ajude alguém.
fonte
Eu tenho uma tabela que se esqueça de adicionar uma chave primária na linha de identificação. Embora seja, tem auto_increment no id. Mas um dia, algumas coisas repetem o log do mysql bin no banco de dados, que insere algumas linhas duplicadas.
Eu removo a linha 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;
exclua as linhas duplicadas por id
insira a linha dos dados exportados.
Em seguida, adicione a chave primária no id
fonte
Eu gosto de ser um pouco mais específico sobre quais registros excluo, então aqui está minha solução:
fonte
Você pode excluir facilmente os registros duplicados desse código.
fonte
Eu tive que fazer isso com campos de texto e me deparei com o limite de 100 bytes no índice.
Resolvi isso adicionando uma coluna, fazendo um hash md5 dos campos e fazendo o alter.
fonte