Je suis nouveau dans SQL en général et je dois supprimer tous les doublons dans une base de données donnée.
Pour le moment, j'utilise cette base de données pour expérimenter certaines choses.
Le tableau ressemble actuellement à ceci:
Je sais que je peux trouver tous les doublons en utilisant cette requête:
SELECT COUNT(*) AS NBR_DOUBLES, Name, Owner
FROM dbo.animals
GROUP BY Name, Owner
HAVING COUNT(*) > 1
Mais j'ai beaucoup de mal à trouver une solution adaptée et mise à jour pour non seulement trouver tous les doublons, mais aussi les supprimer tous, ne laissant qu'un de chacun.
Merci beaucoup d'avoir pris un peu de votre temps pour m'aider.
2 réponses
Utilisez CTE
. Je vais vous montrer un échantillon:
Create table #Table1(Field1 varchar(100));
Insert into #Table1 values
('a'),('b'),('f'),('g'),('a'),('b');
Select * from #Table1;
WITH CTE AS(
SELECT Field1,
RN = ROW_NUMBER()OVER(PARTITION BY Field1 ORDER BY Field1)
FROM #Table1
)
--SELECT * FROM CTE WHERE RN > 1
DELETE FROM CTE WHERE RN > 1
Ce que je fais, c'est , numéroter les lignes. S'il y a des doublons basés sur des colonnes PARTITION BY
, il sera numéroté séquentiellement, sinon 1.
Supprimez ensuite les enregistrements dont le nombre est supérieur à 1.
Je ne vais pas vous nourrir à la cuillère, vous devrez donc jouer avec PARTITION BY pour atteindre votre sortie
Production :
Select * from #Table1;
Field1
---------
a
b
f
g
a
b
/*with cte as (...) SELECT * FROM CTE;*/
Field1 RN
------- -----
a 1
a 2
b 1
b 2
f 1
g 1
Ce que vous voulez faire, c'est utiliser une projection qui numérote chaque enregistrement dans un jeu de doublons donné. Vous pouvez le faire avec un Fonction de fenêtrage, comme ceci:
SELECT Name, Owner
,Row_Number() OVER ( PARTITION BY Name, Owner ORDER BY Name, Owner, Birth) AS RowNum
FROM dbo.animals
ORDER BY Name, Owner
Cela devrait vous donner des résultats comme celui-ci:
Name Owner RowNum Ecstasy Sacha 1 Ecstasy Sacha 2 Ecstasy Sacha 3 Gremlin Max 1 Gremlin Max 2 Gremlin Max 3 Outch Max 1 Outch Max 2 Outch Max 3
Vous voulez maintenant le convertir en une instruction DELETE
qui a une clause WHERE
ciblant les lignes avec RowNum > 1
. La façon d'utiliser une fonction de fenêtrage avec un DELETE
consiste d'abord à inclure la fonction de fenêtrage dans le cadre d'une expression de table commune (CTE), comme ceci:
WITH dupes AS
(
SELECT Name, Owner,
Row_Number() OVER ( PARTITION BY Name, Owner ORDER BY Name, Owner, Birth) AS RowNum
FROM dbo.animals
)
DELETE FROM dupes WHERE RowNum > 1;
Cela supprimera les doublons ultérieurs, mais laissera la ligne n ° 1 pour chaque groupe intacte. Le seul truc maintenant est de s'assurer que la ligne n ° 1 est la bonne ligne, car tous vos doublons n'ont pas les mêmes valeurs pour les colonnes Birth
ou Death
. C'est la raison pour laquelle j'ai inclus la colonne Birth
dans la fonction de fenêtrage, contrairement à d'autres réponses (jusqu'à présent). Vous devez décider si vous souhaitez garder l'animal le plus âgé ou le plus jeune, et éventuellement modifier l'ordre Birth
dans la clause OVER
en fonction de vos besoins.
De nouvelles questions
sql-server
Microsoft SQL Server est un système de gestion de base de données relationnelle (SGBDR). Utilisez cette balise pour toutes les éditions de SQL Server, y compris Compact, Express, Azure, Fast-track, APS (anciennement PDW) et Azure SQL DW. N'utilisez pas cette balise pour d'autres types de SGBD (MySQL, PostgreSQL, Oracle, etc.). N'utilisez pas cette balise pour des problèmes de développement logiciel et mobile, sauf si elle est directement liée à la base de données.