J'ai une table avec une colonne varchar et j'aimerais trouver tous les enregistrements ayant des valeurs en double dans cette colonne. Quelle est la meilleure requête que je peux utiliser pour trouver les doublons?
Faites une SELECT
avec une clause GROUP BY
. Disons name est la colonne dans laquelle vous voulez trouver des doublons:
SELECT name, COUNT(*) c FROM table GROUP BY name HAVING c > 1;
Cela retournera un résultat avec la valeur name dans la première colonne et le nombre de fois où cette valeur apparaîtra dans la seconde.
SELECT varchar_col
FROM table
GROUP BY varchar_col
HAVING COUNT(*) > 1;
SELECT *
FROM mytable mto
WHERE EXISTS
(
SELECT 1
FROM mytable mti
WHERE mti.varchar_column = mto.varchar_column
LIMIT 1, 1
)
Cette requête renvoie des enregistrements complets, pas seulement des varchar_column
distincts.
Cette requête n'utilise pas COUNT(*)
. S'il y a beaucoup de doublons, COUNT(*)
coûte cher et vous n'avez pas besoin de la totalité de COUNT(*)
, vous devez simplement savoir s'il y a deux lignes de même valeur.
Avoir un index sur varchar_column
accélérera bien sûr cette requête.
En vous basant sur la réponse de levik pour obtenir les identifiants des lignes en double, vous pouvez créer un GROUP_CONCAT
si votre serveur le prend en charge (cela retournera une liste d'identifiants séparés par des virgules).
SELECT GROUP_CONCAT(id), name, COUNT(*) c FROM documents GROUP BY name HAVING c > 1;
SELECT *
FROM `dps`
WHERE pid IN (SELECT pid FROM `dps` GROUP BY pid HAVING COUNT(pid)>1)
En supposant que votre table s'appelle TableABC et que la colonne souhaitée soit Col et que la clé primaire en T1 soit Key.
SELECT a.Key, b.Key, a.Col
FROM TableABC a, TableABC b
WHERE a.Col = b.Col
AND a.Key <> b.Key
L'avantage de cette approche par rapport à la réponse ci-dessus est qu'elle donne la clé.
Pour rechercher le nombre d'enregistrements dupliqués dans la colonne Nom de Employee, la requête ci-dessous est utile.
Select name from employee group by name having count(*)>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
Remplacez ville par votre table. Remplacez name par votre nom de champ
Ma dernière requête a incorporé quelques-unes des réponses ici qui ont aidé - combinant groupe par, compte & GROUP_CONCAT.
SELECT GROUP_CONCAT(id), `magento_simple`, COUNT(*) c
FROM product_variant
GROUP BY `magento_simple` HAVING c > 1;
Ceci fournit l'identifiant des deux exemples (séparés par des virgules), le code à barres dont j'avais besoin et le nombre de doublons.
Modifiez le tableau et les colonnes en conséquence.
Je ne vois aucune approche JOIN, qui a de nombreuses utilisations en termes de doublons
Cette approche vous donne des résultats réels doublés.
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
J'ai vu le résultat ci-dessus et la requête fonctionnera correctement si vous devez vérifier la valeur d'une colonne qui est en double. Par exemple email.
Mais si vous devez vérifier avec plus de colonnes et souhaitez vérifier la combinaison du résultat, cette requête fonctionnera correctement:
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)
Prenant @ maxyfc réponse plus loin, il me fallait trouver tout des lignes renvoyées avec les valeurs en double pour pouvoir les modifier dans MySQL Workbench :
SELECT * FROM table
WHERE field IN (
SELECT field FROM table GROUP BY field HAVING count(*) > 1
) ORDER BY field
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
Ce qui suit trouvera tous les product_id qui sont utilisés plus d’une fois. Vous n'obtenez qu'un seul enregistrement pour chaque product_id.
SELECT product_id FROM oc_product_reward GROUP BY product_id HAVING count( product_id ) >1
Code provenant de: 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, '[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)
SELECT DISTINCT a.email FROM `users` a LEFT JOIN `users` b ON a.email = b.email WHERE a.id != b.id;
Une contribution très tardive ... au cas où cela aiderait n'importe qui à passer à travers la ligne ... j'avais la tâche de trouver des paires de transactions correspondantes (en fait, les deux côtés d'un virement de compte à compte) dans une application bancaire, pour identifier lesquelles étaient les 'de' et 'à' pour chaque transaction de transfert entre comptes, nous avons donc abouti à ceci:
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;
Le résultat est que le DuplicateResultsTable
fournit des lignes contenant des transactions correspondantes (c'est-à-dire dupliquées), mais il fournit également le même identifiant de transaction inversé la deuxième fois qu'il correspond à la même paire, de sorte que le SELECT
extérieur est là groupez par le premier ID de transaction, en utilisant LEAST
et GREATEST
pour vous assurer que les deux identificateurs de transaction sont toujours dans le même ordre dans les résultats, ce qui sécurise GROUP
par le premier, éliminant ainsi toutes les correspondances en double. A parcouru près d'un million de records et identifié plus de 12 000 matches en un peu moins de 2 secondes. Bien sûr, le transactionid est l’indice primaire, ce qui a vraiment aidé.
Pour supprimer les lignes en double avec plusieurs champs, annulez-les d'abord sur la nouvelle clé unique spécifiée pour les seules lignes distinctes puis utilisez la commande "group by" pour supprimer les lignes en double avec la même nouvelle clé unique:
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;
Select column_name, column_name1,column_name2, count(1) as temp from table_name group by column_name having temp > 1
Je préfère utiliser les fonctions fenêtrées (MySQL 8.0+) pour trouver les doublons car je pouvais voir la ligne entière:
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;
pour obtenir toutes les données contenant des doublons, j’ai utilisé ceci:
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 = la table avec laquelle vous travaillez.
DupliactedData = les données dupliquées que vous recherchez.
Essayez d'utiliser cette requête:
SELECT name, COUNT(*) value_count FROM company_master GROUP BY name HAVING value_count > 1;
SELECT ColumnA, COUNT( * )
FROM Table
GROUP BY ColumnA
HAVING COUNT( * ) > 1