Pergunta

Eu quero retirar registros duplicados em um banco de dados MySQL. Isso pode ser feito com:

SELECT address, count(id) as cnt FROM list
GROUP BY address HAVING cnt > 1

o que resulta em:

100 MAIN ST    2

Gostaria de puxá-lo para que ele mostra cada linha que é uma duplicata. Algo como:

JIM    JONES    100 MAIN ST
JOHN   SMITH    100 MAIN ST

Quaisquer pensamentos sobre como isso pode ser feito? Estou tentando evitar fazer o primeiro, em seguida, olhando para cima as duplicatas com uma segunda consulta no código.

Foi útil?

Solução

A chave é reescrever essa consulta para que ele possa ser usado como uma subconsulta.

SELECT firstname, 
   lastname, 
   list.address 
FROM list
   INNER JOIN (SELECT address
               FROM   list
               GROUP  BY address
               HAVING COUNT(id) > 1) dup
           ON list.address = dup.address;

Outras dicas

SELECT date FROM logs group by date having count(*) >= 2

Porque não basta INNER JOIN a tabela com si?

SELECT a.firstname, a.lastname, a.address
FROM list a
INNER JOIN list b ON a.address = b.address
WHERE a.id <> b.id

A DISTINCT é necessário se o endereço poderia existir mais de duas vezes.

Eu tentei a melhor resposta escolhida para esta pergunta, mas me confundiu um pouco. Na verdade, eu precisava que apenas em um único campo de minha mesa. O exemplo a seguir de este link trabalhou muito bem para mim:

SELECT COUNT(*) c,title FROM `data` GROUP BY title HAVING c > 1;
select `cityname` from `codcities` group by `cityname` having count(*)>=2

Esta é a consulta semelhante que você pediu e seu 200% funcionando e fácil também. Aproveite !!!

Localizar usuários duplicados endereço de e-mail com esta consulta ...

SELECT users.name, users.uid, users.mail, from_unixtime(created)
FROM users
INNER JOIN (
  SELECT mail
  FROM users
  GROUP BY mail
  HAVING count(mail) > 1
) dupes ON users.mail = dupes.mail
ORDER BY users.mail;

Não é este o mais fácil:

SELECT *
FROM tc_tariff_groups
GROUP BY group_id
HAVING COUNT(group_id) >1

?

podemos encontrar as duplicatas depende de mais do que um campo also.For Nesses casos, você pode usar abaixo formato.

SELECT COUNT(*), column1, column2 
FROM tablename
GROUP BY column1, column2
HAVING COUNT(*)>1;

Outra solução seria usar aliases de tabela, assim:

SELECT p1.id, p2.id, p1.address
FROM list AS p1, list AS p2
WHERE p1.address = p2.address
AND p1.id != p2.id

Tudo o que você está fazendo realmente, neste caso, está tomando o original lista mesa, criando duas p tabelas retend - p 1 e p 2 - fora disso, e em seguida, executar uma junção na coluna de endereço (linha 3). A 4ª linha garante que o mesmo registro não aparecer várias vezes em seu conjunto de resultados ( "duplicatas duplicados").

Finding duplicado endereços é muito mais complexa do que parece, especialmente se você precisar de precisão. Uma consulta MySQL não é suficiente neste caso ...

Eu trabalho em SmartyStreets , onde fazemos a validação de endereços e de duplicação e outras coisas, e eu vi um monte de diversos desafios com problemas semelhantes.

Existem vários serviços de terceiros, que duplicatas bandeira vontade em uma lista para você. Fazer isso apenas com uma subconsulta MySQL não serão responsáveis ??por diferenças de formatos e padrões de endereço. O USPS (para endereço nos EUA) tem algumas orientações para torná-los padrão, mas apenas um punhado de fornecedores são certificados para realizar tais operações.

Então, eu recomendaria a melhor resposta para você é para exportar a tabela em um arquivo CSV, por exemplo, e submetê-lo a um processador de lista capaz. Um desses é LiveAddress que vai tê-lo feito para você em poucos segundos a alguns minutos automaticamente. Ele vai linhas bandeira duplicados com um novo campo chamado "Duplicate" e um valor de Y nele.

Não vai ser muito eficiente, mas deve funcionar:

SELECT *
FROM list AS outer
WHERE (SELECT COUNT(*)
        FROM list AS inner
        WHERE inner.address = outer.address) > 1;

Isso irá selecionar duplicatas em uma passagem mesa, há subconsultas.

SELECT  *
FROM    (
        SELECT  ao.*, (@r := @r + 1) AS rn
        FROM    (
                SELECT  @_address := 'N'
                ) vars,
                (
                SELECT  *
                FROM
                        list a
                ORDER BY
                        address, id
                ) ao
        WHERE   CASE WHEN @_address <> address THEN @r := 0 ELSE 0 END IS NOT NULL
                AND (@_address := address ) IS NOT NULL
        ) aoo
WHERE   rn > 1

Esta consulta emula actially ROW_NUMBER() presente em Oracle e SQL Server

Veja o artigo no meu blog para mais detalhes:

Isso também irá mostrar-lhe como muitas duplicatas tem e vai ordenar os resultados sem se junta

SELECT  `Language` , id, COUNT( id ) AS how_many
FROM  `languages` 
GROUP BY  `Language` 
HAVING how_many >=2
ORDER BY how_many DESC
 SELECT firstname, lastname, address FROM list
 WHERE 
 Address in 
 (SELECT address FROM list
 GROUP BY address
 HAVING count(*) > 1)
select * from table_name t1 inner join (select distinct <attribute list> from table_name as temp)t2 where t1.attribute_name = t2.attribute_name

Para sua mesa seria algo como

select * from list l1 inner join (select distinct address from list as list2)l2 where l1.address=l2.address

Esta consulta vai lhe dar todas as entradas de endereços distintos na lista de sua mesa ... Eu não sei como isso vai funcionar se você tiver quaisquer valores de chave primária para o nome, etc ..

Fastest remoção duplicatas consulta procedimento:

/* create temp table with one primary column id */
INSERT INTO temp(id) SELECT MIN(id) FROM list GROUP BY (isbn) HAVING COUNT(*)>1;
DELETE FROM list WHERE id IN (SELECT id FROM temp);
DELETE FROM temp;

Pessoalmente esta consulta tem resolvido o meu problema:

SELECT `SUB_ID`, COUNT(SRV_KW_ID) as subscriptions FROM `SUB_SUBSCR` group by SUB_ID, SRV_KW_ID HAVING subscriptions > 1;

O que este script faz é mostrar todos os do assinante ID que existe mais de uma vez na tabela e o número de duplicatas encontradas.

Isto são as colunas da tabela:

| SUB_SUBSCR_ID | int(11)     | NO   | PRI | NULL    | auto_increment |
| MSI_ALIAS     | varchar(64) | YES  | UNI | NULL    |                |
| SUB_ID        | int(11)     | NO   | MUL | NULL    |                |    
| SRV_KW_ID     | int(11)     | NO   | MUL | NULL    |                |

A esperança que será útil para você também!

SELECT t.*,(select count(*) from city as tt where tt.name=t.name) as count FROM `city` as t where (select count(*) from city as tt where tt.name=t.name) > 1 order by count desc

Substitua cidade com sua mesa. Substitua nome com o seu nome de campo

    SELECT *
    FROM (SELECT  address, COUNT(id) AS cnt
    FROM list
    GROUP BY address
    HAVING ( COUNT(id) > 1 ))

Powerlord resposta é realmente o melhor e eu recomendaria mais uma mudança: Limite o uso para certificar-db não iria ficar sobrecarregado:

SELECT firstname, lastname, list.address FROM list
INNER JOIN (SELECT address FROM list
GROUP BY address HAVING count(id) > 1) dup ON list.address = dup.address
LIMIT 10

É um bom hábito de uso do limite, se não houver onde e quando tomada de junta. Comece com pequeno valor, verificar quão pesado a consulta é e, em seguida, aumentar o limite.

    Find duplicate Records:

    Suppose we have table : Student 
    student_id int
    student_name varchar
    Records:
    +------------+---------------------+
    | student_id | student_name        |
    +------------+---------------------+
    |        101 | usman               |
    |        101 | usman               |
    |        101 | usman               |
    |        102 | usmanyaqoob         |
    |        103 | muhammadusmanyaqoob |
    |        103 | muhammadusmanyaqoob |
    +------------+---------------------+

    Now we want to see duplicate records
    Use this query:


   select student_name,student_id ,count(*) c from student group by student_id,student_name having c>1;

+--------------------+------------+---+
| student_name        | student_id | c |
+---------------------+------------+---+
| usman               |        101 | 3 |
| muhammadusmanyaqoob |        103 | 2 |
+---------------------+------------+---+

Para ver rapidamente as linhas duplicadas você pode executar uma única consulta simples

Aqui eu estou consultando a tabela e listar todas as linhas duplicadas com o mesmo user_id, market_place e sku:

select user_id, market_place,sku, count(id)as totals from sku_analytics group by user_id, market_place,sku having count(id)>1;

Para excluir a linha duplicada você tem que decidir qual linha que pretende eliminar. Por exemplo, aquele com id inferior (geralmente mais velhos) ou talvez alguma outra informação da data. No meu caso eu só quero excluir o id mais baixo desde o mais recente id é a informação mais recente.

Primeiro verifique se os registros corretos serão apagados. Aqui eu estou selecionando o registro entre os duplicados que serão eliminados (por id único).

select a.user_id, a.market_place,a.sku from sku_analytics a inner join sku_analytics b where a.id< b.id and a.user_id= b.user_id and a.market_place= b.market_place and a.sku = b.sku;

Então eu executar a consulta de exclusão para excluir os incautos:

delete a from sku_analytics a inner join sku_analytics b where a.id< b.id and a.user_id= b.user_id and a.market_place= b.market_place and a.sku = b.sku;

Backup, verificação dupla, verificar, verificar de backup, em seguida, executar.

select address from list where address = any (select address from (select address, count(id) cnt from list group by address having cnt > 1 ) as t1) order by address

o sub-consulta interna retorna linhas com endereço duplicado, em seguida, o sub-consulta externa retorna o endereço de coluna para o endereço com duplicados. o sub-consulta externa deve retornar apenas uma coluna porque ele é utilizado como operando para o operador '= qualquer'

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top