Znajdowanie zduplikowanych wartości w MySQL

Mam tabelę z kolumną varchar i chciałbym znaleźć wszystkie rekordy, które mają zduplikowane wartości w tej kolumnie. Jakie jest najlepsze zapytanie, którego mogę użyć, aby znaleźć duplikaty?

 624
Author: Jon Tackabury, 2009-03-27

21 answers

Wykonaj SELECT z GROUP BY klauzulą. Załóżmy, że Nazwa jest kolumną, w której chcesz znaleźć duplikaty:

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

Zwróci wynik z wartością name w pierwszej kolumnie i liczbą, ile razy ta wartość pojawia się w drugiej.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
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
        )

To zapytanie zwraca pełne rekordy, a nie tylko odrębne varchar_column ' s.

To zapytanie nie używa COUNT(*). Jeśli istnieje wiele duplikatów, COUNT(*) jest drogie i nie potrzebujesz całego COUNT(*), Musisz tylko wiedzieć, czy istnieją dwa wiersze o tej samej wartości.

Posiadanie indeksu na varchar_column oczywiście znacznie przyspieszy to zapytanie.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-27 10:54:39

Bazując na odpowiedzi levika, aby uzyskać identyfikatory zduplikowanych wierszy, możesz wykonać GROUP_CONCAT, Jeśli twój serwer ją obsługuje (zwróci to oddzieloną przecinkami listę identyfikatorów).

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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-22 15:05:46

Zakładając, że Twoja tabela ma nazwę TableABC i kolumnę, którą chcesz, to Col, a kluczem głównym do T1 jest Key.

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

Zaletą tego podejścia nad powyższą odpowiedzią jest to, że daje klucz.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-27 04:29:28

Aby dowiedzieć się, ile rekordów jest duplikatów w kolumnie nazwa w pracowniku, pomocne jest poniższe zapytanie;

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/doraprojects.net/template/agent.layouts/content.php on line 54
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

Zastąp Miasto swoją tabelą. Zastąp nazwę nazwą pola

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-01 22:19:23

Moje ostatnie zapytanie zawierało kilka odpowiedzi, które pomogły-łączenie group by, count & GROUP_CONCAT.

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

To wyświetla id obu przykładów (rozdzielone przecinkami), Kod kreskowy, którego potrzebowałem i ile duplikatów.

Odpowiednio zmienić tabelę i kolumny.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-05 02:38:17

Widziałem powyższy wynik i zapytanie będzie działać dobrze, jeśli chcesz sprawdzić wartość pojedynczej kolumny, która jest zduplikowana. Na przykład e-mail.

Ale jeśli chcesz sprawdzić więcej kolumn i chcesz sprawdzić kombinację wyniku, aby to zapytanie działało poprawnie:

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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-21 08:59:37

Poniżej znajdują się wszystkie product_id, które są używane więcej niż raz. Dla każdego identyfikatora produktu otrzymujesz tylko jeden rekord.

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

Kod zaczerpnięty z : 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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-08 16:59:46

Biorąc @odpowiedź maxyfc dalej, musiałem znaleźć wszystkie wierszy, które zostały zwrócone z zduplikowanymi wartościami, aby móc je edytować w 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/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-01 22:29:58

Nie widzę żadnych aproach JOIN, whitch ma wiele zastosowań pod względem duplikatów.

Ten aproeach daje rzeczywiste podwojone wyniki.

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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 12:33:34

Aby usunąć zduplikowane wiersze z wieloma polami, najpierw anuluj je do nowego unikalnego klucza, który jest określony dla tylko odrębnych wierszy, a następnie użyj polecenia "group by", aby usunąć zduplikowane wiersze z tym samym nowym unikalnym kluczem:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-05 03:31:24

Jeden bardzo spóźniony wkład... na wypadek, gdyby to komuś pomogło... Miałem zadanie znaleźć pasujące pary transakcji (właściwie obie strony przelewów między kontami) w aplikacji bankowej, aby określić, które z nich były " od " I " do " dla każdej transakcji między kontami, więc skończyło się na tym: {]}

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;

Wynikiem jest to, że DuplicateResultsTable dostarcza wiersze zawierające pasujące (np. zduplikowane) transakcje, ale również podaje ten sam identyfikator transakcji w Odwróć drugi raz, gdy pasuje do tej samej pary, więc zewnętrzny {[2] } jest tam do grupowania według pierwszego ID transakcji, co odbywa się za pomocą LEAST i GREATEST, Aby upewnić się, że dwa transactionid są zawsze w tej samej kolejności w wynikach, co czyni go bezpiecznym dla GROUP przez pierwszy, eliminując w ten sposób wszystkie duplikaty dopasowań. Przekroczył prawie milion rekordów i zidentyfikował ponad 12 000 meczów w niecałe 2 sekundy. Oczywiście transactionid jest głównym indeksem, co naprawdę pomogło.

 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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-21 06:46:22

Wolę używać funkcji okienkowych (MySQL 8.0+), aby znaleźć duplikaty, ponieważ mogłem zobaczyć cały wiersz:

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/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-12 17:40:11