web-dev-qa-db-fra.com

Comment obtenir le code T-SQL pour trouver des doublons?

MS Access a un bouton pour générer du code SQL pour trouver des lignes en double. Je ne sais pas si SQL Server 2005/2008 a Managment Studio.

  1. Si tel est le cas, veuillez indiquer où

  2. Si ce n'est pas le cas, dites-moi comment puis-je avoir un assistant T-SQL pour créer un code comme celui-ci.

50
Jader Dias

Eh bien, si vous avez des lignes entières comme doublons dans votre table, vous n'avez au moins pas de clé primaire configurée pour cette table, sinon au moins la valeur de la clé primaire serait différente.

Cependant, voici comment créer un SQL pour obtenir des doublons sur un ensemble de colonnes:

SELECT col1, col2, col3, col4
FROM table
GROUP BY col1, col2, col3, col4
HAVING COUNT(*) > 1

Cela trouvera des lignes qui, pour les colonnes col1-col4, ont la même combinaison de valeurs, plusieurs fois.

Par exemple, dans le tableau suivant, les lignes 2 + 3 seraient des doublons:

PK    col1    col2    col3    col4    col5
1       1       2       3       4      6
2       1       3       4       7      7
3       1       3       4       7      10
4       2       3       1       4      5

Les deux lignes partagent des valeurs communes dans les colonnes col1-col4 et sont donc considérées comme des doublons par ce code SQL. Développez la liste des colonnes pour contenir toutes les colonnes pour lesquelles vous souhaitez analyser cela.

119

Si vous utilisez SQL Server 2005+, vous pouvez utiliser le code suivant pour afficher toutes les lignes avec d'autres colonnes:

SELECT *, ROW_NUMBER() OVER (PARTITION BY col1, col2, col3, col4 ORDER BY (SELECT 0)) AS DuplicateRowNumber
FROM table

Youd peut également supprimer (ou travailler avec) des doublons en utilisant cette technique:

WITH cte AS
(SELECT *, ROW_NUMBER() OVER (PARTITION BY col1, col2, col3, col4 ORDER BY (SELECT 0)) AS DuplicateRowNumber
    FROM table
)
DELETE FROM cte WHERE DuplicateRowNumber > 1

ROW_NUMBER est extrêmement puissant - vous pouvez faire beaucoup avec cela - voir l'article de BOL à ce sujet à http://msdn.Microsoft.com/en-us/library/ms186734.aspx

57
Mike DeFehr

J'ai trouvé cette solution lorsque je dois vider des lignes entières avec un ou plusieurs champs en double, mais je ne souhaite pas taper tous les noms de champs de la table:

SELECT * FROM db WHERE col IN
    (SELECT col FROM db GROUP BY col HAVING COUNT(*) > 1)
    ORDER BY col
5
Ferruccio

Autant que je sache. Il vous suffit de créer une instruction select regroupant tous les champs d'une table et de la filtrer à l'aide d'une clause having où le nombre est supérieur à 1.

Si vos lignes sont dupliquées sauf par la clé, n'incluez pas la clé dans les champs sélectionnés.

2
eKek0

Une autre façon de procéder consiste à joindre une table sur elle-même.

SELECT *
FROM dbo.TableA aBase
JOIN dbo.TableA aDupes ON aDupes.ColA = aBase.ColA AND
                          aDupes.ColB = aBase.ColB
WHERE aBase.Pkey < aDupes.Pkey

Remarque: La clé aBase.Pkey <aDupes.Pkey existe parce que la jonction d'une table contre elle-même créera deux lignes par correspondance car la condition sera toujours vraie deux fois.

En d'autres termes: Si la table aBase a une ligne égale à une ligne de aDupes (basée sur ColA et ColB), le reflet de cette correspondance sera également vrai - aDupes a une ligne égale à une ligne Base basée sur ColA et ColB. Par conséquent, ces deux correspondances seront renvoyées dans le jeu de résultats.

Limitez ceci/éliminez cette réflexion en choisissant arbitrairement tous les résultats où l'une des tables a une clé inférieure.

<ou> n'a pas d'importance, tant que les touches sont différentes.

Cela permet également de filtrer les correspondances avec une ligne sur elle-même caraBase.Pkey <aDupes.Pkeyoblige les clés primaires à être différentes.

0
boylec1986