Encontrar valores duplicados en MySQL


Tengo una tabla con una columna varchar, y me gustaría encontrar todos los registros que tienen valores duplicados en esta columna. ¿Cuál es la mejor consulta que puedo usar para encontrar los duplicados?

 624
Author: Jon Tackabury, 2009-03-27

21 answers

Haga un SELECT con una cláusula GROUP BY. Digamos que name es la columna en la que desea encontrar duplicados:

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

Esto devolverá un resultado con el valor name en la primera columna, y un recuento de cuántas veces ese valor aparece en la segunda.

 1231
Author: levik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-21 23:33:10
SELECT varchar_col
FROM table
GROUP BY varchar_col
HAVING count(*) > 1;
 182
Author: maxyfc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-27 04:27:16
SELECT  *
FROM    mytable mto
WHERE   EXISTS
        (
        SELECT  1
        FROM    mytable mti
        WHERE   mti.varchar_column = mto.varchar_column
        LIMIT 1, 1
        )

Esta consulta devuelve registros completos, no solo distintos varchar_column.

Esta consulta no utiliza COUNT(*). Si hay muchos duplicados, COUNT(*) es caro, y no necesita todo COUNT(*), solo necesita saber si hay dos filas con el mismo valor.

Tener un índice en varchar_column, por supuesto, acelerará esta consulta en gran medida.

 138
Author: Quassnoi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-27 10:54:39

Construyendo a partir de la respuesta de levik para obtener los ID de las filas duplicadas, puede hacer un GROUP_CONCAT si su servidor lo admite (esto devolverá una lista de ID separados por comas).

SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUP BY name HAVING c > 1;
 107
Author: Matt Rardon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-19 00:56:21
SELECT * 
FROM `dps` 
WHERE pid IN (SELECT pid FROM `dps` GROUP BY pid HAVING COUNT(pid)>1)
 11
Author: strustam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-22 15:05:46

Suponiendo que su tabla se llama TableABC y la columna que desea es Col y la clave principal de T1 es Clave.

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

La ventaja de este enfoque sobre la respuesta anterior es que da la Clave.

 9
Author: TechTravelThink,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-27 04:29:28

Para encontrar cuántos registros son duplicados en la columna nombre en Empleado, la siguiente consulta es útil;

Select name from employee group by name having count(*)>1;
 9
Author: user5599549,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-24 13:23:41
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

Sustitúyase ciudad por su Tabla. Reemplazar nombre con su nombre de campo

 7
Author: Lalit Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-01 22:19:23

Mi consulta final incorporó algunas de las respuestas aquí que ayudaron: combinar group by, count & GROUP_CONCAT.

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

Esto proporciona el id de ambos ejemplos (separados por comas), el código de barras que necesitaba y cuántos duplicados.

Cambie la tabla y las columnas en consecuencia.

 5
Author: Jonathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-05 02:38:17

Vi el resultado anterior y la consulta funcionará bien si necesita verificar el valor de una sola columna que están duplicados. Por ejemplo, correo electrónico.

Pero si necesita verificar con más columnas y desea verificar la combinación del resultado para que esta consulta funcione bien:

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)
 4
Author: user2235601,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-23 15:11:07
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
 3
Author: magesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-21 08:59:37

A continuación encontrará todos los product_id que se utilizan más de una vez. Solo se obtiene un único registro para cada product_id.

SELECT product_id FROM oc_product_reward GROUP BY product_id HAVING count( product_id ) >1

Código tomado de : http://chandreshrana.blogspot.in/2014/12/find-duplicate-records-based-on-any.html

 3
Author: Chandresh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-30 13:52:46
CREATE TABLE tbl_master
    (`id` int, `email` varchar(15));

INSERT INTO tbl_master
    (`id`, `email`) VALUES
    (1, '[email protected]'),
    (2, '[email protected]'),
    (3, '[email protected]'),
    (4, '[email protected]'),
    (5, '[email protected]');

QUERY : SELECT id, email FROM tbl_master
WHERE email IN (SELECT email FROM tbl_master GROUP BY email HAVING COUNT(id) > 1)
 3
Author: Bijesh Sheth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-08 16:59:46

Tomando @respuesta de maxyfc además, necesitaba encontrar todas de las filas que se devolvieron con los valores duplicados, para poder editarlas en MySQL Workbench :

SELECT * FROM table
   WHERE field IN (
     SELECT field FROM table GROUP BY field HAVING count(*) > 1
   ) ORDER BY field
 3
Author: AbsoluteƵERØ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-01 22:29:58

No veo ningún acercamiento de UNIÓN, whitch tiene muchos usos en términos de duplicados.

Este enfoque le da resultados reales duplicados.

SELECT t1.* FROM table as t1 LEFT JOIN table as t2 ON t1.name=t2.name and t1.id!=t2.id WHERE t2.id IS NOT NULL ORDER BY t1.name
 3
Author: Adam Fischer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-20 10:33:43
SELECT DISTINCT a.email FROM `users` a LEFT JOIN `users` b ON a.email = b.email WHERE a.id != b.id;
 2
Author: Pawel Furmaniak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-30 12:33:34

Para eliminar filas duplicadas con múltiples campos, primero cancélelas a la nueva clave única que se especifica para las únicas filas distintas, luego use el comando" agrupar por " para eliminar filas duplicadas con la misma clave única nueva:

Create TEMPORARY table tmp select concat(f1,f2) as cfs,t1.* from mytable as t1;
Create index x_tmp_cfs on tmp(cfs);
Create table unduptable select f1,f2,... from tmp group by cfs;
 1
Author: irshst,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-05 03:31:24

Una contribución muy tardía... en caso de que ayude a alguien waaaaaay en la línea... Tuve la tarea de encontrar pares de transacciones coincidentes (en realidad, ambos lados de las transferencias de cuenta a cuenta) en una aplicación bancaria, para identificar cuáles eran los 'de' y 'para' para cada transacción de transferencia entre cuentas, así que terminamos con esto:

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;

El resultado es que el DuplicateResultsTable proporciona filas que contienen transacciones coincidentes (es decir, duplicadas), pero también proporciona los mismos id de transacción en invertir la segunda vez que coincide con el mismo par, por lo que el exterior SELECT está allí para agrupar por el primer ID de transacción, que se hace mediante el uso de LEAST y GREATEST para asegurarse de que los dos id de transacción están siempre en el mismo orden en los resultados, lo que hace que sea seguro para GROUP por el primero, eliminando así todas las coincidencias duplicadas. Pasó por casi un millón de registros e identificó más de 12,000 partidos en poco menos de 2 segundos. Por supuesto, el transactionid es el índice principal, lo que realmente ayudó.

 1
Author: fortyninthnet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-06 14:21:26
Select column_name, column_name1,column_name2, count(1) as temp from table_name group by column_name having temp > 1
 1
Author: Vipin Jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-01 09:41:26
SELECT ColumnA, COUNT( * )
FROM Table
GROUP BY ColumnA
HAVING COUNT( * ) > 1
 0
Author: Scott Ferguson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 06:46:22

Prefiero usar funciones de ventana (MySQL 8.0+) para encontrar duplicados porque puedo ver toda la fila:

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

 0
Author: Lukasz Szozda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-12 17:40:11