tutorial - mysql é gratuito




Encontrando valores duplicados no MySQL (16)

Eu tenho uma tabela com uma coluna varchar e gostaria de encontrar todos os registros que possuem valores duplicados nesta coluna. Qual é a melhor consulta que posso usar para encontrar as duplicatas?



Com base na resposta de levik para obter os IDs das linhas duplicadas, você pode fazer um GROUP_CONCAT se o seu servidor suportar (isto irá retornar uma lista de IDs separados por vírgulas).

SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUP BY name HAVING c > 1;

Eu prefiro usar funções em janelas (MySQL 8.0+) para encontrar duplicatas, porque pude ver a linha inteira:

WITH cte AS (
  SELECT *
    ,COUNT(*) OVER(PARTITION BY col_name) AS num_of_duplicates_group
    ,ROW_NUMBER() OVER(PARTITION BY col_name ORDER BY col_name2) AS pos_in_group
  FROM table
)
SELECT *
FROM cte
WHERE num_of_duplicates_group > 1;

DB Fiddle Demo


Eu vi o resultado acima e consulta irá funcionar bem se você precisar verificar o valor da coluna única que são duplicados. Por exemplo, email.

Mas se você precisa verificar com mais colunas e gostaria de verificar a combinação do resultado para que esta consulta funcione bem:

SELECT COUNT(CONCAT(name,email)) AS tot,
       name,
       email
FROM users
GROUP BY CONCAT(name,email)
HAVING tot>1 (This query will SHOW the USER list which ARE greater THAN 1
              AND also COUNT)

Minha consulta final incorporou algumas das respostas aqui que ajudaram - combinando group by, count e GROUP_CONCAT.

SELECT GROUP_CONCAT(id), `magento_simple`, COUNT(*) c 
FROM product_variant 
GROUP BY `magento_simple` HAVING c > 1;

Isso fornece o ID de ambos os exemplos (separados por vírgula), o código de barras necessário e quantas duplicatas.

Altere a tabela e as colunas de acordo.


Para descobrir quantos registros são duplicados na coluna de nome em Funcionário, a consulta abaixo é útil.

Select name from employee group by name having count(*)>1;

Se você quiser remover o uso duplicado DISTINCT

Caso contrário, use esta consulta:

SELECT users.*,COUNT(user_ID) as user FROM users GROUP BY user_name HAVING user > 1;


Supondo que sua tabela é denominada TableABC e a coluna que você deseja é Col e a chave primária para T1 é Key.

SELECT a.Key, b.Key, a.Col 
FROM TableABC a, TableABC b
WHERE a.Col = b.Col 
AND a.Key <> b.Key

A vantagem dessa abordagem sobre a resposta acima é que ela fornece a chave.


Uma contribuição muito tardia ... no caso de ajudar alguém a perder a linha ... Eu tive a tarefa de encontrar pares de transações (na verdade, ambos os lados de transferências de conta a conta) em um aplicativo bancário, para identificar quais foram os 'de' e 'para' para cada transação de transferência entre contas, então acabamos com isso:

SELECT 
    LEAST(primaryid, secondaryid) AS transactionid1,
    GREATEST(primaryid, secondaryid) AS transactionid2
FROM (
    SELECT table1.transactionid AS primaryid, 
        table2.transactionid AS secondaryid
    FROM financial_transactions table1
    INNER JOIN financial_transactions table2 
    ON table1.accountid = table2.accountid
    AND table1.transactionid <> table2.transactionid 
    AND table1.transactiondate = table2.transactiondate
    AND table1.sourceref = table2.destinationref
    AND table1.amount = (0 - table2.amount)
) AS DuplicateResultsTable
GROUP BY transactionid1
ORDER BY transactionid1;

O resultado é que o DuplicateResultsTable fornece linhas contendo transações correspondentes (ou seja, duplicadas), mas também fornece o mesmo id de transação na segunda vez em que corresponde ao mesmo par, portanto o SELECT externo está lá para agrupar pelo primeiro ID de transação, que é feito usando LEAST e GREATEST para garantir que as duas transações estejam sempre na mesma ordem nos resultados, o que torna seguro GROUP pela primeira, eliminando assim todas as correspondências duplicadas. Passou por quase um milhão de registros e identificou mais de 12.000 partidas em menos de 2 segundos. Claro que o transactionid é o índice primário, o que realmente ajudou.


Faça um SELECT com uma cláusula GROUP BY . Digamos que name seja a coluna na qual você deseja encontrar duplicatas:

SELECT name, COUNT(*) c FROM table GROUP BY name HAVING c > 1;

Isso retornará um resultado com o valor do nome na primeira coluna e uma contagem de quantas vezes esse valor aparece no segundo.


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

SELECT  *
FROM    mytable mto
WHERE   EXISTS
        (
        SELECT  1
        FROM    mytable mti
        WHERE   mti.varchar_column = mto.varchar_column
        LIMIT 1, 1
        )

Esta consulta retorna registros completos, não apenas varchar_column distintos.

Esta consulta não usa COUNT(*) . Se houver muitos duplicados, COUNT(*) é caro e você não precisa de todo o COUNT(*) , basta saber se há duas linhas com o mesmo valor.

Ter um índice em varchar_column , é claro, acelera bastante essa consulta.


SELECT * 
FROM `dps` 
WHERE pid IN (SELECT pid FROM `dps` GROUP BY pid HAVING COUNT(pid)>1)

SELECT ColumnA, COUNT( * )
FROM Table
GROUP BY ColumnA
HAVING COUNT( * ) > 1

SELECT varchar_col
FROM table
GROUP BY varchar_col
HAVING COUNT(*) > 1;

Select column_name, column_name1,column_name2, count(1) as temp from table_name group by column_name having temp > 1




mysql