J'ai une base de données d'organisations SQL Server et il y a beaucoup de lignes en double. Je souhaite exécuter une instruction select pour récupérer tout cela et la quantité de dupes, mais aussi renvoyer les identifiants associés à chaque organisation.
Une déclaration comme:
SELECT orgName, COUNT(*) AS dupes
FROM organizations
GROUP BY orgName
HAVING (COUNT(*) > 1)
Retournera quelque chose comme
orgName | dupes
ABC Corp | 7
Foo Federation | 5
Widget Company | 2
Mais j'aimerais aussi en saisir les identifiants. Est-ce qu'il y a un moyen de faire ça? Peut-être comme un
orgName | dupeCount | id
ABC Corp | 1 | 34
ABC Corp | 2 | 5
...
Widget Company | 1 | 10
Widget Company | 2 | 2
La raison en est qu’il existe également un tableau séparé des utilisateurs qui sont liés à ces organisations, et je voudrais les unifier (par conséquent, supprimez les dupes afin que les utilisateurs se connectent à la même organisation plutôt que des organisations de dupe). Mais je voudrais une partie manuellement afin de ne rien foirer, mais il me faudrait quand même une déclaration renvoyant les identifiants de toutes les organisations dupliquées pour pouvoir consulter la liste des utilisateurs.
select o.orgName, oc.dupeCount, o.id
from organizations o
inner join (
SELECT orgName, COUNT(*) AS dupeCount
FROM organizations
GROUP BY orgName
HAVING COUNT(*) > 1
) oc on o.orgName = oc.orgName
Vous pouvez exécuter la requête suivante et rechercher les doublons avec max(id)
et supprimer ces lignes.
SELECT orgName, COUNT(*), Max(ID) AS dupes
FROM organizations
GROUP BY orgName
HAVING (COUNT(*) > 1)
Mais vous devrez exécuter cette requête plusieurs fois.
Vous pouvez le faire comme ça:
SELECT
o.id, o.orgName, d.intCount
FROM (
SELECT orgName, COUNT(*) as intCount
FROM organizations
GROUP BY orgName
HAVING COUNT(*) > 1
) AS d
INNER JOIN organizations o ON o.orgName = d.orgName
Si vous souhaitez ne renvoyer que les enregistrements pouvant être supprimés (en en laissant un de chaque), vous pouvez utiliser:
SELECT
id, orgName
FROM (
SELECT
orgName, id,
ROW_NUMBER() OVER (PARTITION BY orgName ORDER BY id) AS intRow
FROM organizations
) AS d
WHERE intRow != 1
Edit: SQL Server 2000 n'a pas la fonction ROW_NUMBER (). Au lieu de cela, vous pouvez utiliser:
SELECT
o.id, o.orgName, d.intCount
FROM (
SELECT orgName, COUNT(*) as intCount, MIN(id) AS minId
FROM organizations
GROUP BY orgName
HAVING COUNT(*) > 1
) AS d
INNER JOIN organizations o ON o.orgName = d.orgName
WHERE d.minId != o.id
La solution marquée comme correcte ne fonctionnait pas pour moi, mais j'ai trouvé cette réponse qui fonctionnait à merveille: obtenir la liste des lignes en double dans MySql
SELECT n1.*
FROM myTable n1
INNER JOIN myTable n2
ON n2.repeatedCol = n1.repeatedCol
WHERE n1.id <> n2.id
Tu peux essayer ça, c'est mieux pour toi
WITH CTE AS
(
SELECT *,RN=ROW_NUMBER() OVER (PARTITION BY orgName ORDER BY orgName DESC) FROM organizations
)
select * from CTE where RN>1
go
select * from [Employees]
Pour trouver des doublons Enregistrement 1) Utilisation de CTE
with mycte
as
(
select Name,EmailId,ROW_NUMBER() over(partition by Name,EmailId order by id) as Duplicate from [Employees]
)
select * from mycte
2) En utilisant GroupBy
select Name,EmailId,COUNT(name) as Duplicate from [Employees] group by Name,EmailId
Si vous souhaitez supprimer les doublons:
WITH CTE AS(
SELECT orgName,id,
RN = ROW_NUMBER()OVER(PARTITION BY orgName ORDER BY Id)
FROM organizations
)
DELETE FROM CTE WHERE RN > 1
Select * from (Select orgName,id,
ROW_NUMBER() OVER(Partition By OrgName ORDER by id DESC) Rownum
From organizations )tbl Where Rownum>1
Ainsi, les enregistrements avec rowum> 1 seront les enregistrements en double dans votre table. 'Partitionnez par' premier groupe par les enregistrements, puis sérialisez-les en leur donnant les numéros de série. Donc, rownum> 1 seront les enregistrements en double qui pourraient être supprimés en tant que tels.
select column_name, count(column_name)
from table_name
group by column_name
having count (column_name) > 1;
select a.orgName,b.duplicate, a.id
from organizations a
inner join (
SELECT orgName, COUNT(*) AS duplicate
FROM organizations
GROUP BY orgName
HAVING COUNT(*) > 1
) b on o.orgName = oc.orgName
group by a.orgName,a.id
select orgname, count(*) as dupes, id
from organizations
where orgname in (
select orgname
from organizations
group by orgname
having (count(*) > 1)
)
group by orgname, id
Vous avez plusieurs possibilités pour sélectionner duplicate rows
.
pour mes solutions, considérons d'abord ce tableau par exemple
CREATE TABLE #Employee
(
ID INT,
FIRST_NAME NVARCHAR(100),
LAST_NAME NVARCHAR(300)
)
INSERT INTO #Employee VALUES ( 1, 'Ardalan', 'Shahgholi' );
INSERT INTO #Employee VALUES ( 2, 'name1', 'lname1' );
INSERT INTO #Employee VALUES ( 3, 'name2', 'lname2' );
INSERT INTO #Employee VALUES ( 2, 'name1', 'lname1' );
INSERT INTO #Employee VALUES ( 3, 'name2', 'lname2' );
INSERT INTO #Employee VALUES ( 4, 'name3', 'lname3' );
Première solution:
SELECT DISTINCT *
FROM #Employee;
WITH #DeleteEmployee AS (
SELECT ROW_NUMBER()
OVER(PARTITION BY ID, First_Name, Last_Name ORDER BY ID) AS
RNUM
FROM #Employee
)
SELECT *
FROM #DeleteEmployee
WHERE RNUM > 1
SELECT DISTINCT *
FROM #Employee
Solution secondaire: Utilisez le champ identity
SELECT DISTINCT *
FROM #Employee;
ALTER TABLE #Employee ADD UNIQ_ID INT IDENTITY(1, 1)
SELECT *
FROM #Employee
WHERE UNIQ_ID < (
SELECT MAX(UNIQ_ID)
FROM #Employee a2
WHERE #Employee.ID = a2.ID
AND #Employee.FIRST_NAME = a2.FIRST_NAME
AND #Employee.LAST_NAME = a2.LAST_NAME
)
ALTER TABLE #Employee DROP COLUMN UNIQ_ID
SELECT DISTINCT *
FROM #Employee
et fin de toute solution utiliser cette commande
DROP TABLE #Employee
Supposons que nous ayons la table 'Student' avec 2 colonnes:
student_id int
student_name varchar
Records:
+------------+---------------------+
| student_id | student_name |
+------------+---------------------+
| 101 | usman |
| 101 | usman |
| 101 | usman |
| 102 | usmanyaqoob |
| 103 | muhammadusmanyaqoob |
| 103 | muhammadusmanyaqoob |
+------------+---------------------+
Maintenant, nous voulons voir les enregistrements en double Utilisez cette requête:
select student_name,student_id ,count(*) c from student group by student_id,student_name having c>1;
+---------------------+------------+---+
| student_name | student_id | c |
+---------------------+------------+---+
| usman | 101 | 3 |
| muhammadusmanyaqoob | 103 | 2 |
+---------------------+------------+---+
J'ai une meilleure option pour obtenir les enregistrements en double dans une table
SELECT x.studid, y.stdname, y.dupecount
FROM student AS x INNER JOIN
(SELECT a.stdname, COUNT(*) AS dupecount
FROM student AS a INNER JOIN
studmisc AS b ON a.studid = b.studid
WHERE (a.studid LIKE '2018%') AND (b.studstatus = 4)
GROUP BY a.stdname
HAVING (COUNT(*) > 1)) AS y ON x.stdname = y.stdname INNER JOIN
studmisc AS z ON x.studid = z.studid
WHERE (x.studid LIKE '2018%') AND (z.studstatus = 4)
ORDER BY x.stdname
Le résultat de la requête ci-dessus montre tous les noms en double avec des ID d'étudiant uniques et le nombre d'occurrences en double.
/*To get duplicate data in table */
SELECT COUNT(EmpCode),EmpCode FROM tbl_Employees WHERE Status=1
GROUP BY EmpCode HAVING COUNT(EmpCode) > 1
je pense que je sais ce dont vous avez besoin, je devais mélanger les réponses et je pense avoir la solution qu'il cherchait:
select o.id,o.orgName, oc.dupeCount, oc.id,oc.orgName
from organizations o
inner join (
SELECT MAX(id) as id, orgName, COUNT(*) AS dupeCount
FROM organizations
GROUP BY orgName
HAVING COUNT(*) > 1
) oc on o.orgName = oc.orgName
avoir le max id vous donnera l'identifiant du duplicate et celui de l'original qui correspond à ce qu'il a demandé:
id org name , dublicate count (missing out in this case)
id doublicate org name , doub count (missing out again because does not help in this case)
seule chose triste que vous obtenez mis dans cette forme
id , name , dubid , name
espérons que cela aide toujours