Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

4 façons de vérifier les lignes en double dans SQL Server

Voici quatre méthodes que vous pouvez utiliser pour rechercher des lignes en double dans SQL Server.

Par "lignes en double", j'entends deux lignes ou plus qui partagent exactement les mêmes valeurs dans toutes les colonnes.

Exemple de données

Supposons que nous ayons un tableau avec les données suivantes :

SELECT * FROM Pets;

Résultat :

+---------+-----------+-----------+
| PetId   | PetName   | PetType   |
|---------+-----------+-----------|
| 1       | Wag       | Dog       |
| 1       | Wag       | Dog       |
| 2       | Scratch   | Cat       |
| 3       | Tweet     | Bird      |
| 4       | Bark      | Dog       |
| 4       | Bark      | Dog       |
| 4       | Bark      | Dog       |
+---------+-----------+-----------+

Nous pouvons voir que les deux premières lignes sont des doublons, tout comme les trois dernières lignes.

Option 1

Nous pouvons utiliser la requête suivante pour renvoyer des informations sur les lignes en double :

SELECT 
    DISTINCT PetId, 
    COUNT(*) AS "Count"
FROM Pets
GROUP BY PetId
ORDER BY PetId;

Résultat :

+---------+---------+
| PetId   | Count   |
|---------+---------|
| 1       | 2       |
| 2       | 1       |
| 3       | 1       |
| 4       | 3       |
+---------+---------+

Nous pouvons développer le SELECT list pour inclure plus de colonnes si nécessaire :

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY PetId;

Résultat :

+---------+-----------+-----------+---------+
| PetId   | PetName   | PetType   | Count   |
|---------+-----------+-----------+---------|
| 1       | Wag       | Dog       | 2       |
| 2       | Scratch   | Cat       | 1       |
| 3       | Tweet     | Bird      | 1       |
| 4       | Bark      | Dog       | 3       |
+---------+-----------+-----------+---------+

Si la table a un identifiant unique, nous pouvons simplement supprimer cette colonne de la requête. Par exemple, si nous supposons que le PetId est en fait une colonne de clé primaire contenant un identifiant unique, nous pourrions exécuter la requête suivante pour renvoyer toutes les lignes qui sont des doublons, sans compter la colonne de clé primaire :

SELECT 
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetName,
    PetType
ORDER BY PetName;

Résultat :

+-----------+-----------+---------+
| PetName   | PetType   | Count   |
|-----------+-----------+---------|
| Bark      | Dog       | 3       |
| Scratch   | Cat       | 1       |
| Tweet     | Bird      | 1       |
| Wag       | Dog       | 2       |
+-----------+-----------+---------+

Option 2

Si nous voulons que seules les lignes en double réelles soient renvoyées, nous pouvons ajouter le HAVING clause :

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
HAVING COUNT(*) > 1
ORDER BY PetId;

Résultat :

+---------+-----------+-----------+---------+
| PetId   | PetName   | PetType   | Count   |
|---------+-----------+-----------+---------|
| 1       | Wag       | Dog       | 2       |
| 4       | Bark      | Dog       | 3       |
+---------+-----------+-----------+---------+

Option 3

Une autre façon de le faire est d'utiliser le ROW_NUMBER() fonction avec le PARTITION BY clause pour numéroter la sortie du jeu de résultats.

SELECT 
    *, 
    ROW_NUMBER() OVER ( 
        PARTITION BY PetId, PetName, PetType 
        ORDER BY PetId, PetName, PetType
        ) AS Row_Number
FROM Pets;

Résultat :

+---------+-----------+-----------+--------------+
| PetId   | PetName   | PetType   | Row_Number   |
|---------+-----------+-----------+--------------|
| 1       | Wag       | Dog       | 1            |
| 1       | Wag       | Dog       | 2            |
| 2       | Scratch   | Cat       | 1            |
| 3       | Tweet     | Bird      | 1            |
| 4       | Bark      | Dog       | 1            |
| 4       | Bark      | Dog       | 2            |
| 4       | Bark      | Dog       | 3            |
+---------+-----------+-----------+--------------+

La PARTITION BY la clause divise le jeu de résultats produit par le FROM clause en partitions auxquelles la fonction est appliquée. Lorsque nous spécifions des partitions pour le jeu de résultats, chaque partition fait recommencer la numérotation (c'est-à-dire que la numérotation commencera à 1 pour la première ligne de chaque partition).

Option 4

Si nous voulons que seules les lignes excédentaires des doublons correspondants soient renvoyées, nous pouvons utiliser la requête ci-dessus comme expression de table commune, comme ceci :

WITH CTE AS 
    (
        SELECT 
            *, 
            ROW_NUMBER() OVER ( 
                PARTITION BY PetId, PetName, PetType 
                ORDER BY PetId, PetName, PetType
                ) AS Row_Number
        FROM Pets
    )
SELECT * FROM CTE WHERE Row_Number <> 1;

Résultat :

+---------+-----------+-----------+--------------+
| PetId   | PetName   | PetType   | Row_Number   |
|---------+-----------+-----------+--------------|
| 1       | Wag       | Dog       | 2            |
| 4       | Bark      | Dog       | 2            |
| 4       | Bark      | Dog       | 3            |
+---------+-----------+-----------+--------------+

L'un des avantages de cette opération est que nous pouvons supprimer les lignes en double simplement en changeant SELECT * pour DELETE (sur la dernière ligne).

Par conséquent, nous pouvons utiliser le code ci-dessus pour voir quelles lignes seront supprimées, puis lorsque nous sommes convaincus que nous allons supprimer les lignes correctes, nous pouvons le remplacer par un DELETE pour les supprimer réellement.

Comme ceci :

WITH CTE AS 
    (
        SELECT 
            *, 
            ROW_NUMBER() OVER ( 
                PARTITION BY PetId, PetName, PetType 
                ORDER BY PetId, PetName, PetType
                ) AS Row_Number
        FROM Pets
    )
DELETE FROM CTE WHERE Row_Number <> 1;