Ich habe eine Tabelle mit einer Varchar-Spalte und möchte alle Datensätze mit doppelten Werten in dieser Spalte finden. Was ist die beste Abfrage, mit der ich die Duplikate finden kann?
Ich habe eine Tabelle mit einer Varchar-Spalte und möchte alle Datensätze mit doppelten Werten in dieser Spalte finden. Was ist die beste Abfrage, mit der ich die Duplikate finden kann?
Antworten:
Mach ein SELECT
mit einer GROUP BY
Klausel. Angenommen, Name ist die Spalte, in der Sie Duplikate finden möchten:
SELECT name, COUNT(*) c FROM table GROUP BY name HAVING c > 1;
Dies gibt ein Ergebnis mit dem Namenswert in der ersten Spalte und einer Zählung zurück, wie oft dieser Wert in der zweiten Spalte angezeigt wird.
GROUP_CONCAT(id)
und es werden die IDs aufgelistet . Siehe meine Antwort für ein Beispiel.
ERROR: column "c" does not exist LINE 1
?
SELECT varchar_col
FROM table
GROUP BY varchar_col
HAVING COUNT(*) > 1;
IN()
/ NOT IN()
.
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_column
.
Diese Abfrage wird nicht verwendet COUNT(*)
. Wenn es viele Duplikate gibt, COUNT(*)
teuer ist und Sie nicht das Ganze benötigen COUNT(*)
, müssen Sie nur wissen, ob es zwei Zeilen mit demselben Wert gibt.
Wenn Sie einen Index für haben, varchar_column
wird diese Abfrage natürlich erheblich beschleunigt.
ORDER BY varchar_column DESC
habe am Ende der Abfrage hinzugefügt .
GROUP BY
und HAVING
gibt nur eine der möglichen Duplikate. Außerdem Leistung mit indiziertem Feld anstelle von COUNT(*)
und die Möglichkeit, ORDER BY
doppelte Datensätze zu gruppieren.
Aufbauend auf der Antwort von levik, um die IDs der doppelten Zeilen zu erhalten, können Sie eine ausführen, GROUP_CONCAT
wenn 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;
SELECT id, GROUP_CONCAT(id), name, COUNT(*) c [...]
die Inline-Bearbeitung und sollte alle beteiligten Zeilen aktualisieren (oder zumindest die erste übereinstimmende), aber leider erzeugt die Bearbeitung einen Javascript-Fehler. ..
Angenommen, Ihre Tabelle heißt 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 besteht darin, dass er den Schlüssel gibt.
Um herauszufinden, wie viele Datensätze in der Namensspalte des Mitarbeiters doppelt vorhanden sind, ist die folgende Abfrage hilfreich.
Select name from employee group by name having count(*)>1;
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;
TableName = die Tabelle, mit der Sie arbeiten.
DupliactedData = die duplizierten Daten, nach denen Sie suchen.
Meine letzte Abfrage enthielt einige der Antworten, die hier geholfen haben - das Kombinieren von Gruppieren nach, Zählen & GROUP_CONCAT.
SELECT GROUP_CONCAT(id), `magento_simple`, COUNT(*) c
FROM product_variant
GROUP BY `magento_simple` HAVING c > 1;
Dies gibt die ID beider Beispiele (durch Kommas getrennt), den von mir benötigten Barcode und die Anzahl der Duplikate an.
Ändern Sie Tabelle und Spalten entsprechend.
Ich sehe keine JOIN-Ansätze, die in Bezug auf Duplikate viele Verwendungszwecke haben.
Dieser Ansatz liefert Ihnen tatsächlich doppelte Ergebnisse.
SELECT t1.* FROM my_table as t1
LEFT JOIN my_table as t2
ON t1.name=t2.name and t1.id!=t2.id
WHERE t2.id IS NOT NULL
ORDER BY t1.name
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 die Stadt durch Ihren Tisch. Ersetzen Sie den Namen durch Ihren Feldnamen
Unter @ maxyfc der Antwort weiter, ich brauchte finden alle der Zeilen , die mit den doppelten Werten zurückgegeben wurden, so dass ich sie in bearbeiten könnte MySQL Workbench :
SELECT * FROM table
WHERE field IN (
SELECT field FROM table GROUP BY field HAVING count(*) > 1
) ORDER BY field
Ich habe das obige Ergebnis gesehen und die Abfrage funktioniert einwandfrei, wenn Sie doppelte Spaltenwerte überprüfen müssen. Zum Beispiel E-Mail.
Wenn Sie jedoch mit mehr Spalten prüfen müssen und die Kombination des Ergebnisses überprüfen möchten, funktioniert diese Abfrage einwandfrei:
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)
SELECT COUNT(CONCAT(userid,event,datetime)) AS total, userid, event, datetime FROM mytable GROUP BY CONCAT(userid, event, datetime ) HAVING total>1
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;
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
Im Folgenden finden Sie alle product_id, die mehrmals verwendet werden. Sie erhalten nur einen einzigen 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
CREATE TABLE tbl_master
(`id` int, `email` varchar(15));
INSERT INTO tbl_master
(`id`, `email`) VALUES
(1, 'test1@gmail.com'),
(2, 'test2@gmail.com'),
(3, 'test1@gmail.com'),
(4, 'test2@gmail.com'),
(5, 'test5@gmail.com');
QUERY : SELECT id, email FROM tbl_master
WHERE email IN (SELECT email FROM tbl_master GROUP BY email HAVING COUNT(id) > 1)
SELECT DISTINCT a.email FROM `users` a LEFT JOIN `users` b ON a.email = b.email WHERE a.id != b.id;
a.email
zu a.*
und alle die IDs der Zeilen mit Duplikaten zu erhalten.
SELECT DISTINCT a.*
fast sofort gelöst.
Um doppelte Zeilen mit mehreren Feldern zu entfernen, müssen Sie sie zuerst auf den neuen eindeutigen Schlüssel streichen, der für die einzigen unterschiedlichen Zeilen angegeben ist, und dann mit dem Befehl "group by" 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;
CREATE TEMPORARY TABLE ...
? Eine kleine Erklärung Ihrer Lösung wäre großartig.
Ein sehr später Beitrag ... für den Fall, dass es jemandem hilft, auf der ganzen Linie zu warten ... Ich hatte die Aufgabe, passende Transaktionspaare (eigentlich beide Seiten von Konto-zu-Konto-Überweisungen) in einer Bank-App zu finden, um zu identifizieren, welche waren die 'von' und 'bis' für jede Transaktion zwischen Kontotransfers, so dass wir am Ende folgendes hatten:
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 die DuplicateResultsTable
Zeilen Zeilen enthalten, die übereinstimmende (dh doppelte) Transaktionen enthalten, aber auch die gleichen Transaktions-IDs in umgekehrter Reihenfolge bereitstellen, wenn sie zum zweiten Mal mit demselben Paar übereinstimmen, sodass die äußere SELECT
nach der ersten Transaktions-ID gruppiert werden kann durch die NutzungLEAST
und GREATEST
sicherstellen, dass die beiden Transaktions-IDs in den Ergebnissen immer in derselben Reihenfolge sind, was es sicher macht, bis GROUP
zum ersten zu gehen, wodurch alle doppelten Übereinstimmungen eliminiert werden. Durchlief fast eine Million Rekorde und identifizierte mehr als 12.000 Spiele in knapp 2 Sekunden. Natürlich ist die Transaktions-ID der Primärindex, was wirklich geholfen hat.
Select column_name, column_name1,column_name2, count(1) as temp from table_name group by column_name having temp > 1
SELECT ColumnA, COUNT( * )
FROM Table
GROUP BY ColumnA
HAVING COUNT( * ) > 1
Wenn Sie doppelte Verwendung entfernen möchten DISTINCT
Andernfalls verwenden Sie diese Abfrage:
SELECT users.*,COUNT(user_ID) as user FROM users GROUP BY user_name HAVING user > 1;
Versuchen Sie es mit dieser Abfrage:
SELECT name, COUNT(*) value_count FROM company_master GROUP BY name HAVING value_count > 1;