Il est facile de trouver duplicates
avec un champ:
SELECT name, COUNT(email)
FROM users
GROUP BY email
HAVING COUNT(email) > 1
Donc si on a une table
ID NAME EMAIL
1 John [email protected]
2 Sam [email protected]
3 Tom [email protected]
4 Bob [email protected]
5 Tom [email protected]
Cette requête nous donnera John, Sam, Tom, Tom parce qu'ils ont tous la même email
.
Cependant, ce que je veux, c'est obtenir des doublons avec les mêmes email
et name
.
C'est-à-dire que je veux avoir "Tom", "Tom".
La raison pour laquelle j'ai besoin de ceci: j'ai commis une erreur et autorisé à insérer des valeurs dupliquées name
et email
. Maintenant, j'ai besoin de supprimer/changer les doublons, donc je dois 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 prévoyait que toutes les colonnes non agrégées soient regroupé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'attributs dans une relation d'une base de données. En d'autres termes, la dépendance fonctionnelle est une contrainte qui décrit la relation entre des attributs dans une relation.
Le support n'est pas cohérent:
sql_mode=only_full_group_by
: 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 façon beaucoup plus simple de le faire que de devoir rechercher des lignes paires/impaires dans une triple 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 donc 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'un seul de chaque duplicata à chaque fois.
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 de contournement vraiment cool pour trouver tous les ID en double:
SELECT GROUP_CONCAT( id )
FROM users
GROUP BY email
HAVING ( COUNT(email) > 1 )
essayez 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', '[email protected]');
insert into my_users values (2, 'Sam', '[email protected]');
insert into my_users values (3, 'Tom', '[email protected]');
insert into my_users values (4, 'Bob', '[email protected]');
insert into my_users values (5, 'Tom', '[email protected]');
commit;
select *
from my_users
where rowid not in (select min(rowid) from my_users group by name, email);
Ceci sélectionne/supprime tous les enregistrements en double sauf 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 causer des problèmes de performance.
select id,name,COUNT(*) from India group by Id,Name having COUNT(*)>1
Comment pouvons-nous compter les valeurs dupliquées?.
aussi simple que
select COUNT(distinct col_01) from Table_01
Ceci est la chose facile que je suis venu avec. 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 trouve tous les étudiants avec un nom en double et une dob. Les champs que vous souhaitez vérifier pour la duplication vont dans la clause OVER. Vous pouvez inclure tous les autres champs de votre choix 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 name, email
, case
when ROW_NUMBER () over (partition by name, email order by name) > 1 then 'Yes'
else 'No'
end "duplicated ?"
from users
Si vous souhaitez voir s'il existe des lignes en double dans votre table, j'ai utilisé ci-dessous la requête
create table my_table(id int, name varchar(100), email varchar(100));
insert into my_table values (1, 'shekh', '[email protected]');
insert into my_table values (1, 'shekh', '[email protected]');
insert into my_table values (2, 'Aman', '[email protected]');
insert into my_table values (3, 'Tom', '[email protected]');
insert into my_table values (4, 'Raj', '[email protected]');
Select COUNT(1) As Total_Rows from my_table
Select Count(1) As Distinct_Rows from ( Select Distinct * from my_table) abc
Cela devrait également fonctionner, peut-être l'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 nouveau domaine en courrier. alors vous pouvez utiliser replace () dans ces colonnes
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
/
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
Si vous souhaitez rechercher des données en double (selon 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.azurewebsites.net/2014/09/better-sql-group-by-find-duplicate-data/
SELECT * FROM users u where rowid = (select max(rowid) from users u1 where
u.email=u1.email);
Pour vérifier les doublons Enregistrez dans un tableau.
select * from users s
where rowid < any
(select rowid from users k where s.name = k.name and s.email = k.email);
ou
select * from users s
where rowid not in
(select max(rowid) from users k where s.name = k.name and s.email = k.email);
Supprimer l'enregistrement en double dans une table.
delete from users s
where rowid < any
(select rowid from users k where s.name = k.name and s.email = k.email);
ou
delete from users s
where rowid not in
(select max(rowid) from users k where s.name = k.name and s.email = k.email);
Nous pouvons utiliser avoir ici qui travaillent sur les fonctions d'agrégat comme indiqué ci-dessous
create table #TableB (id_account int, data int, [date] date)
insert into #TableB values (1 ,-50, '10/20/2018'),
(1, 20, '10/09/2018'),
(2 ,-900, '10/01/2018'),
(1 ,20, '09/25/2018'),
(1 ,-100, '08/01/2018')
SELECT id_account , data, COUNT(*)
FROM #TableB
GROUP BY id_account , data
HAVING COUNT(id_account) > 1
drop table #TableB
Ici, deux champs id_account et data sont utilisés avec Count (*). Ainsi, il donnera tous les enregistrements qui ont plus d'une fois les mêmes valeurs dans les deux colonnes.
Nous avons eu tort d’avoir omis d’ajouter des contraintes dans la table du serveur SQL et les enregistrements ont été insérés en double dans toutes les colonnes avec application frontale. Ensuite, nous pouvons utiliser la requête ci-dessous pour supprimer la requête en double de la table.
SELECT DISTINCT * INTO #TemNewTable FROM #OriginalTable
TRUNCATE TABLE #OriginalTable
INSERT INTO #OriginalTable SELECT * FROM #TemNewTable
DROP TABLE #TemNewTable
Ici, nous avons pris tous les enregistrements distincts de la table d'origine et supprimé ceux de la table d'origine. De nouveau, nous avons inséré toutes les valeurs distinctes d'une nouvelle table dans la table d'origine, puis supprimé une nouvelle table.
Vous pouvez utiliser le mot clé SELECT DISTINCT pour supprimer les doublons. Vous pouvez également filtrer par nom et que tout le monde porte ce nom sur une table.
Vous voudrez peut-être essayer ceci
SELECT NAME, EMAIL, COUNT(*)
FROM USERS
GROUP BY 1,2
HAVING COUNT(*) > 1
Pour supprimer les enregistrements dont les noms sont en double
;WITH CTE AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY name ORDER BY name) AS T FROM @YourTable
)
DELETE FROM CTE WHERE T > 1