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:

table content

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.

1
ilomax 1 août 2017 à 17:25

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
0
Prabhat G 1 août 2017 à 14:40

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.

1
Joel Coehoorn 1 août 2017 à 15:03