430 votes

Sélectionner une déclaration pour trouver les doublons sur certains champs

Pouvez-vous m'aider avec des instructions SQL pour trouver les doublons sur plusieurs champs ?

Par exemple, en pseudo-code :

select count(field1,field2,field3) 
from table 
where the combination of field1, field2, field3 occurs multiple times

et de la déclaration ci-dessus s'il y a plusieurs occurrences Je voudrais sélectionner tous les enregistrements sauf le premier .

3 votes

Votre pseudo code est ambigu, de plus vous ne définissez pas l'ordre selon lequel vous ne voulez pas le premier. je vous suggère de donner un exemple de données.

866voto

Rajesh Chamarthi Points 8847

Pour obtenir la liste des champs pour lesquels il existe plusieurs enregistrements, vous pouvez utiliser .

select field1,field2,field3, count(*)
  from table_name
  group by field1,field2,field3
  having count(*) > 1

Consultez ce lien pour plus d'informations sur la façon de supprimer les rangs.

http://support.microsoft.com/kb/139444

Il devrait y avoir un critère pour décider comment définir les "premières lignes" avant d'utiliser l'approche du lien ci-dessus. Sur cette base, vous devrez utiliser une clause order by et une sous-requête si nécessaire. Si vous pouvez poster un échantillon de données, cela nous aiderait beaucoup.

46voto

Heinzi Points 66519

Vous mentionnez "le premier", je suppose donc que vous avez une sorte d'ordre sur vos données. Supposons que vos données sont ordonnées par un champ quelconque ID .

Ce SQL devrait vous donner les entrées en double, sauf la première. En fait, il sélectionne toutes les lignes pour lesquelles il existe une autre ligne avec (a) les mêmes champs et (b) un ID inférieur. Les performances ne seront pas excellentes, mais cela pourrait résoudre votre problème.

SELECT A.ID, A.field1, A.field2, A.field3
  FROM myTable A
 WHERE EXISTS (SELECT B.ID
                 FROM myTable B
                WHERE B.field1 = A.field1
                  AND B.field2 = A.field2
                  AND B.field3 = A.field3
                  AND B.ID < A.ID)

19voto

Nick Vaccaro Points 3476

C'est une solution amusante avec SQL Server 2005 que j'aime bien. Je vais supposer que par "pour chaque enregistrement sauf le premier", vous voulez dire qu'il y a une autre colonne "id" que nous pouvons utiliser pour identifier la ligne qui est "première".

SELECT id
    , field1
    , field2
    , field3
FROM
(
    SELECT id
        , field1
        , field2
        , field3
        , RANK() OVER (PARTITION BY field1, field2, field3 ORDER BY id ASC) AS [rank]
    FROM table_name
) a
WHERE [rank] > 1

0 votes

Je viens de remarquer l'étiquette SQL Server 2008. Je suis content que ma suggestion soit toujours valable.

1 votes

Excellente solution car elle renvoie également les lignes qui devront être supprimées de la table en question.

1 votes

Il est utile de considérer la liste des champs de PARTITION BY comme une liste de champs PK.

6voto

manoj Verma Points 11

Pour voir les valeurs dupliquées :

with MYCTE  as (
    select row_number() over ( partition by name  order by name) rown, *
    from tmptest  
    ) 
select * from MYCTE where rown <=1

3voto

Bradford Hoagland Points 221

Si vous utilisez SQL Server 2005 ou une version ultérieure (et que les balises de votre question indiquent SQL Server 2008), vous pouvez utiliser les fonctions de classement pour renvoyer les enregistrements en double après le premier si l'utilisation de jointures est moins souhaitable ou peu pratique pour une raison quelconque. L'exemple suivant montre cela en action, où cela fonctionne également avec des valeurs nulles dans les colonnes examinées.

create table Table1 (
 Field1 int,
 Field2 int,
 Field3 int,
 Field4 int 
)

insert  Table1 
values    (1,1,1,1)
        , (1,1,1,2)
        , (1,1,1,3)
        , (2,2,2,1)
        , (3,3,3,1)
        , (3,3,3,2)
        , (null, null, 2, 1)
        , (null, null, 2, 3)

select    *
from     (select      Field1
                    , Field2
                    , Field3
                    , Field4
                    , row_number() over (partition by   Field1
                                                      , Field2
                                                      , Field3
                                         order by       Field4) as occurrence
          from      Table1) x
where     occurrence > 1

Remarquez après avoir exécuté cet exemple que le premier enregistrement de chaque "groupe" est exclu, et que les enregistrements avec des valeurs nulles sont traités correctement.

Si vous ne disposez pas d'une colonne pour ordonner les enregistrements d'un groupe, vous pouvez utiliser les colonnes partition-by comme colonnes order-by.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X