Recherche de valeurs en double dans une table SQL

Il est facile de trouver des duplicates avec un seul champ:

 SELECT name, COUNT(email) FROM users GROUP BY email HAVING COUNT(email) > 1 

Donc, si nous avons une table

 ID NAME EMAIL 1 John asd@asd.com 2 Sam asd@asd.com 3 Tom asd@asd.com 4 Bob bob@asd.com 5 Tom asd@asd.com 

Cette requête nous donnera John, Sam, Tom, Tom car ils ont tous le même email .

Cependant, ce que je veux, c’est obtenir des doublons avec le même email et le même name .

C’est-à-dire que je veux avoir “Tom”, “Tom”.

La raison pour laquelle j’ai besoin de ceci: j’ai fait une erreur et autorisé à insérer des valeurs de name et de email double. Maintenant, je dois supprimer / modifier les doublons, je dois donc les trouver en premier.

 SELECT name, email, COUNT(*) FROM users GROUP BY name, email HAVING COUNT(*) > 1 

Il suffit de grouper sur les deux colonnes.

Remarque: l’ancienne norme ANSI doit avoir toutes les colonnes non agrégées dans GROUP BY, mais cela a changé avec l’idée de “dépendance fonctionnelle” :

Dans la théorie des bases de données relationnelles, une dépendance fonctionnelle est une contrainte entre deux ensembles d’atsortingbuts dans une relation à partir d’une firebase database. En d’autres termes, la dépendance fonctionnelle est une contrainte qui décrit la relation entre les atsortingbuts d’une relation.

Le support n’est pas cohérent:

  • PostgreSQL ™ récent le supporte .
  • SQL Server (comme à SQL Server 2017) nécessite toujours toutes les colonnes non agrégées dans GROUP BY.
  • MySQL est imprévisible et vous avez besoin de sql_mode=only_full_group_by :
    • GROUP BY lname ORDER BY affichant des résultats incorrects ;
    • Quelle est la fonction d’agrégation la moins chère en l’absence de TOUT () (voir les commentaires dans la réponse acceptée).
  • Oracle n’est pas assez répandu (attention: humour, je ne connais pas Oracle).

essaye ça:

 declare @YourTable table (id int, name varchar(10), email varchar(50)) INSERT @YourTable VALUES (1,'John','John-email') INSERT @YourTable VALUES (2,'John','John-email') INSERT @YourTable VALUES (3,'fred','John-email') INSERT @YourTable VALUES (4,'fred','fred-email') INSERT @YourTable VALUES (5,'sam','sam-email') INSERT @YourTable VALUES (6,'sam','sam-email') SELECT name,email, COUNT(*) AS CountOf FROM @YourTable GROUP BY name,email HAVING COUNT(*)>1 

SORTIE:

 name email CountOf ---------- ----------- ----------- John John-email 2 sam sam-email 2 (2 row(s) affected) 

si vous voulez les identifiants des dups utilisez ceci:

 SELECT y.id,y.name,y.email FROM @YourTable y INNER JOIN (SELECT name,email, COUNT(*) AS CountOf FROM @YourTable GROUP BY name,email HAVING COUNT(*)>1 ) dt ON y.name=dt.name AND y.email=dt.email 

SORTIE:

 id name email ----------- ---------- ------------ 1 John John-email 2 John John-email 5 sam sam-email 6 sam sam-email (4 row(s) affected) 

pour supprimer les doublons, essayez:

 DELETE d FROM @YourTable d INNER JOIN (SELECT y.id,y.name,y.email,ROW_NUMBER() OVER(PARTITION BY y.name,y.email ORDER BY y.name,y.email,y.id) AS RowRank FROM @YourTable y INNER JOIN (SELECT name,email, COUNT(*) AS CountOf FROM @YourTable GROUP BY name,email HAVING COUNT(*)>1 ) dt ON y.name=dt.name AND y.email=dt.email ) dt2 ON d.id=dt2.id WHERE dt2.RowRank!=1 SELECT * FROM @YourTable 

SORTIE:

 id name email ----------- ---------- -------------- 1 John John-email 3 fred John-email 4 fred fred-email 5 sam sam-email (4 row(s) affected) 

Essaye ça:

 SELECT name, email FROM users GROUP BY name, email HAVING ( COUNT(*) > 1 ) 

Si vous souhaitez supprimer les doublons, voici une méthode beaucoup plus simple que de devoir trouver des lignes paires / impaires dans une sortingple sous-sélection:

 SELECT id, name, email FROM users u, users u2 WHERE u.name = u2.name AND u.email = u2.email AND u.id > u2.id 

Et pour supprimer:

 DELETE FROM users WHERE id IN ( SELECT id/*, name, email*/ FROM users u, users u2 WHERE u.name = u2.name AND u.email = u2.email AND u.id > u2.id ) 

Beaucoup plus facile à lire et à comprendre à mon humble avis

Remarque: le seul problème est que vous devez exécuter la demande jusqu’à ce qu’aucune ligne ne soit supprimée, car vous ne supprimez qu’une fois chaque copie.

Essayez ce qui suit:

 SELECT * FROM ( SELECT Id, Name, Age, Comments, Row_Number() OVER(PARTITION BY Name, Age ORDER By Name) AS Rank FROM Customers ) AS B WHERE Rank>1 
  SELECT name, email FROM users WHERE email in (SELECT email FROM users GROUP BY email HAVING COUNT(*)>1) 

Un peu tard pour la fête, mais j’ai trouvé une solution vraiment cool pour trouver tous les ID en double:

 SELECT GROUP_CONCAT( id ) FROM users GROUP BY email HAVING ( COUNT(email) > 1 ) 

essayer ce code

 WITH CTE AS ( SELECT Id, Name, Age, Comments, RN = ROW_NUMBER()OVER(PARTITION BY Name,Age ORDER BY ccn) FROM ccnmaster ) select * from CTE 

Si vous travaillez avec Oracle, cette méthode serait préférable:

 create table my_users(id number, name varchar2(100), email varchar2(100)); insert into my_users values (1, 'John', 'asd@asd.com'); insert into my_users values (2, 'Sam', 'asd@asd.com'); insert into my_users values (3, 'Tom', 'asd@asd.com'); insert into my_users values (4, 'Bob', 'bob@asd.com'); insert into my_users values (5, 'Tom', 'asd@asd.com'); commit; select * from my_users where rowid not in (select min(rowid) from my_users group by name, email); 

Cela permet de sélectionner / supprimer tous les enregistrements en double, à l’exception d’un enregistrement de chaque groupe de doublons. Ainsi, la suppression laisse tous les enregistrements uniques + un enregistrement de chaque groupe de doublons.

Sélectionnez les doublons:

 SELECT * FROM table WHERE id NOT IN ( SELECT MIN(id) FROM table GROUP BY column1, column2 ); 

Supprimer les doublons:

 DELETE FROM table WHERE id NOT IN ( SELECT MIN(id) FROM table GROUP BY column1, column2 ); 

Soyez conscient de plus grandes quantités d’enregistrements, cela peut entraîner des problèmes de performance.

 select id,name,COUNT(*) from India group by Id,Name having COUNT(*)>1 

Si vous souhaitez voir s’il y a des lignes en double dans votre table, j’ai utilisé ci-dessous Requête:

 create table my_table(id int, name varchar(100), email varchar(100)); insert into my_table values (1, 'shekh', 'shekh@rms.com'); insert into my_table values (1, 'shekh', 'shekh@rms.com'); insert into my_table values (2, 'Aman', 'aman@rms.com'); insert into my_table values (3, 'Tom', 'tom@rms.com'); insert into my_table values (4, 'Raj', 'raj@rms.com'); Select COUNT(1) As Total_Rows from my_table Select Count(1) As Distinct_Rows from ( Select Distinct * from my_table) abc 

Comment on peut compter les valeurs dupliquées? soit il est répété 2 fois ou plus grand que 2. il suffit de les compter, et non pas du sharepoint vue du groupe.

aussi simple que

 select COUNT(distinct col_01) from Table_01 

C’est la chose la plus facile que j’ai imaginée. Il utilise une expression de table commune (CTE) et une fenêtre de partition (je pense que ces fonctionnalités sont dans SQL 2008 et versions ultérieures).

Cet exemple recherche tous les étudiants avec un nom et un dob dupliqués. Les champs que vous souhaitez vérifier pour la duplication figurent dans la clause OVER. Vous pouvez inclure tout autre champ souhaité dans la projection.

 with cte (StudentId, Fname, LName, DOB, RowCnt) as ( SELECT StudentId, FirstName, LastName, DateOfBirth as DOB, SUM(1) OVER (Partition By FirstName, LastName, DateOfBirth) as RowCnt FROM tblStudent ) SELECT * from CTE where RowCnt > 1 ORDER BY DOB, LName 

SELECT id, COUNT(id) FROM table1 GROUP BY id HAVING COUNT(id)>1;

Je pense que cela fonctionnera correctement pour rechercher des valeurs répétées dans une colonne particulière.

Cela devrait aussi marcher, peut-être essayer.

  Select * from Users a where EXISTS (Select * from Users b where ( a.name = b.name OR a.email = b.email) and a.ID != b.id) 

Particulièrement bien dans votre cas Si vous recherchez des doublons qui ont une sorte de préfixe ou un changement général comme par exemple un nouveau domaine dans le courrier. alors vous pouvez utiliser replace () sur ces colonnes

 select name, email , case when ROW_NUMBER () over (partition by name, email order by name) > 1 then 'Yes' else 'No' end "duplicated ?" from users 
  select emp.ename, emp.empno, dept.loc from emp inner join dept on dept.deptno=emp.deptno inner join (select ename, count(*) from emp group by ename, deptno having count(*) > 1) t on emp.ename=t.ename order by emp.ename / 

Si vous souhaitez rechercher des données en double (par un ou plusieurs critères) et sélectionnez les lignes réelles.

 with MYCTE as ( SELECT DuplicateKey1 ,DuplicateKey2 --optional ,count(*) X FROM MyTable group by DuplicateKey1, DuplicateKey2 having count(*) > 1 ) SELECT E.* FROM MyTable E JOIN MYCTE cte ON E.DuplicateKey1=cte.DuplicateKey1 AND E.DuplicateKey2=cte.DuplicateKey2 ORDER BY E.DuplicateKey1, E.DuplicateKey2, CreatedAt 

http://developer.azureewebsites.net/2014/09/better-sql-group-by-find-duplicate-data/

En utilisant CTE, nous pouvons également trouver une valeur en double comme celle-ci

 with MyCTE as ( select Name,EmailId,ROW_NUMBER() over(PARTITION BY EmailId order by id) as Duplicate from [Employees] ) select * from MyCTE where Duplicate>1 
 SELECT * FROM users u where rowid = (select max(rowid) from users u1 where u.email=u1.email); 

SELECT column_name,COUNT(*) FROM TABLE_NAME GROUP BY column1, HAVING COUNT(*) > 1;

 SELECT FirstName, LastName, MobileNo, COUNT(1) as CNT FROM CUSTOMER GROUP BY FirstName, LastName, MobileNo HAVING COUNT(1) > 1;