wake-up-neo.com

Doppelte Werte in MySQL suchen

Ich habe eine Tabelle mit einer Varchar-Spalte und möchte alle Datensätze finden, die doppelte Werte in dieser Spalte enthalten. Was ist die beste Abfrage, die ich verwenden kann, um die Duplikate zu finden?

671
Jon Tackabury

Führen Sie eine SELECT mit einer GROUP BY-Klausel aus. Nehmen wir an, name ist die Spalte, in der Duplikate suchen sollen:

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

Dadurch wird ein Ergebnis mit dem Wert name in der ersten Spalte zurückgegeben und eine Zählung, wie oft dieser Wert in der zweiten Spalte erscheint.

1346
levik
SELECT varchar_col
FROM table
GROUP BY varchar_col
HAVING COUNT(*) > 1;
200
maxyfc
SELECT  *
FROM    mytable mto
WHERE   EXISTS
        (
        SELECT  1
        FROM    mytable mti
        WHERE   mti.varchar_column = mto.varchar_column
        LIMIT 1, 1
        )

Diese Abfrage gibt vollständige Datensätze zurück, nicht nur eindeutige varchar_columns.

Diese Abfrage verwendet COUNT(*) nicht. Wenn es viele Duplikate gibt, ist COUNT(*) teuer und Sie brauchen nicht die gesamte COUNT(*). Sie müssen nur wissen, ob es zwei Zeilen mit demselben Wert gibt.

Mit einem Index für varchar_column wird diese Abfrage natürlich erheblich beschleunigt.

149
Quassnoi

Wenn Sie die Antwort von levik nutzen, um die IDs der doppelten Zeilen zu erhalten, können Sie einen GROUP_CONCAT ausführen, falls Ihr Server dies unterstützt (dies gibt eine durch Kommas getrennte Liste von IDs zurück).

SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUP BY name HAVING c > 1;
116
Matt Rardon
SELECT * 
FROM `dps` 
WHERE pid IN (SELECT pid FROM `dps` GROUP BY pid HAVING COUNT(pid)>1)
12
strustam

Angenommen, Ihre Tabelle hat den Namen TableABC und die gewünschte Spalte ist Col und der Primärschlüssel für T1 ist Key.

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

Der Vorteil dieses Ansatzes gegenüber der obigen Antwort ist der Schlüssel.

11
TechTravelThink

Um herauszufinden, wie viele Datensätze in der Namensspalte in Employee vorhanden sind, ist die folgende Abfrage hilfreich.

Select name from employee group by name having count(*)>1;
9
user5599549
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

Ersetzen Sie city durch Ihre Tabelle. Ersetzen Sie name durch Ihren Feldnamen

7
Lalit Patel

Meine letzte Abfrage enthielt einige der Antworten, die hier geholfen haben - Gruppieren nach, Zählen und GROUP_CONCAT.

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

Dies liefert die ID beider Beispiele (durch Kommas getrennt), den benötigten Barcode und wie viele Duplikate.

Ändern Sie die Tabelle und die Spalten entsprechend.

6
Jonathan

Ich sehe keine JOIN-Ansätze, die im Hinblick auf Duplikate vielfältig sind. 

Dieser Ansatz liefert Ihnen tatsächlich doppelte Ergebnisse.

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
6
Adam Fischer

Ich habe das obige Ergebnis gesehen und die Abfrage funktioniert einwandfrei, wenn Sie einen einzelnen Spaltenwert überprüfen müssen, der doppelt vorhanden ist. Zum Beispiel eine E-Mail.

Wenn Sie jedoch nach mehr Spalten suchen müssen und die Kombination des Ergebnisses prüfen möchten, funktioniert diese Abfrage gut:

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)
5
user2235601

Bei der Antwort von @ maxyfc musste ich all der Zeilen finden, die mit den doppelten Werten zurückgegeben wurden, damit ich sie in MySQL Workbench bearbeiten konnte

SELECT * FROM table
   WHERE field IN (
     SELECT field FROM table GROUP BY field HAVING count(*) > 1
   ) ORDER BY field
4
AbsoluteƵERØ
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
magesh

Im Folgenden finden Sie alle product_id, die mehr als einmal verwendet werden. Sie erhalten nur einen einzelnen Datensatz für jede product_id.

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

Code entnommen aus: http://chandreshrana.blogspot.in/2014/12/find-duplicate-records-based-on-any.html

3
Chandresh
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
Bijesh Sheth
SELECT DISTINCT a.email FROM `users` a LEFT JOIN `users` b ON a.email = b.email WHERE a.id != b.id;
2
Pawel Furmaniak

Ein sehr später Beitrag ... falls es jemandem hilft, auf der ganzen Linie zu warten ... Ich hatte die Aufgabe, übereinstimmende Transaktionspaare (eigentlich beide Seiten von Konto-zu-Konto-Überweisungen) in einer Banking-App zu finden, um welche zu identifizieren waren die 'von' und 'bis' für jede Überweisungstransaktion, so dass wir am Ende so waren:

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;

Das Ergebnis ist, dass DuplicateResultsTable Zeilen enthält, die übereinstimmende (dh doppelte) Transaktionen enthalten, aber es liefert auch die umgekehrten Transaktions-IDs, wenn sie zum zweiten Mal mit demselben Paar übereinstimmen, sodass die äußere SELECT dort nach der ersten Transaktions-ID gruppiert wird Dies geschieht durch Verwendung von LEAST und GREATEST, um sicherzustellen, dass die beiden Transaktions-IDs immer in der gleichen Reihenfolge in den Ergebnissen sind. Dadurch ist es möglich, GROUP durch die erste zu ersetzen, wodurch alle doppelten Übereinstimmungen eliminiert werden. Durchlief fast eine Million Datensätze und identifizierte 12.000 Spiele in weniger als zwei Sekunden. Natürlich ist die Transaktions-ID der Primärindex, was wirklich geholfen hat.

1
fortyninthnet

Um doppelte Zeilen mit mehreren Feldern zu entfernen, müssen Sie sie zuerst für den neuen eindeutigen Schlüssel, der für die einzelnen unterschiedlichen Zeilen angegeben ist, kategorisieren. Anschließend können Sie mit dem Befehl "Gruppieren nach" doppelte Zeilen mit demselben neuen eindeutigen Schlüssel entfernen:

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
irshst

Wenn Sie doppelte Einträge entfernen möchten, verwenden Sie DISTINCT

Andernfalls verwenden Sie diese Abfrage:

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

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

Ich bevorzuge die Verwendung von Fensterfunktionen (MySQL 8.0+), um Duplikate zu finden, da ich die gesamte Zeile sehen konnte:

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

1
Lukasz Szozda

um alle Daten zu erhalten, die Duplikate enthalten, habe ich Folgendes verwendet:

SELECT * FROM TableName INNER JOIN(
  SELECT DupliactedData FROM TableName GROUP BY DupliactedData HAVING COUNT(DupliactedData) > 1 order by DupliactedData)
  temp ON TableName.DupliactedData = temp.DupliactedData;

Tabellenname = die Tabelle, mit der Sie arbeiten.

DupliactedData = die duplizierten Daten, nach denen Sie suchen.

0
udi

Versuchen Sie es mit dieser Abfrage:

SELECT name, COUNT(*) value_count FROM company_master GROUP BY name HAVING value_count > 1;
0
Atul Akabari
SELECT ColumnA, COUNT( * )
FROM Table
GROUP BY ColumnA
HAVING COUNT( * ) > 1
0
Scott Ferguson