Les exemples suivants renvoient des lignes en double à partir d'une table de base de données Oracle.
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
Les deux premières lignes sont des doublons, tout comme les trois dernières lignes. Dans ce cas, les lignes en double contiennent des valeurs en double dans toutes les colonnes, y compris la colonne ID.
Option 1
Nous pouvons utiliser la requête suivante pour voir combien de lignes sont des doublons :
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
Nous avons regroupé les lignes par toutes les colonnes et renvoyé le nombre de lignes de chaque groupe. Toute ligne dont le nombre est supérieur à 1 est un doublon.
Nous pouvons le classer par nombre dans l'ordre décroissant, de sorte que les lignes avec le plus de doublons apparaissent en premier :
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
ORDER BY Count(*) DESC;
Résultat :
PETID PETNAME PETTYPE Count 4 Bark Dog 3 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 1
Option 2
Si nous ne voulons que les lignes en double répertoriées, nous pouvons utiliser le HAVING
clause pour renvoyer uniquement les lignes dont le nombre est supérieur à 1 :
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC;
Résultat :
PETID PETNAME PETTYPE Count 4 Bark Dog 3 1 Wag Dog 2
Option 3
Une autre option consiste à utiliser le ROW_NUMBER()
fonction fenêtre :
SELECT
PetId,
PetName,
PetType,
ROW_NUMBER() OVER (
PARTITION BY PetId, PetName, PetType
ORDER BY PetId, PetName, PetType
) AS rn
FROM Pets;
Résultat :
PETID PETNAME PETTYPE RN 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
Nous pouvons utiliser la requête ci-dessus comme expression de table commune :
WITH cte AS
(
SELECT
PetId,
PetName,
PetType,
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
Cela renvoie uniquement les lignes en excès des doublons correspondants. Donc s'il y a deux lignes identiques, il renvoie l'une d'entre elles. S'il y a trois lignes identiques, il en renvoie deux, et ainsi de suite.
Option 5
Étant donné que notre table ne contient pas de colonne de clé primaire, nous pouvons tirer parti du rowid
d'Oracle pseudo-colonne :
SELECT * FROM Pets
WHERE EXISTS (
SELECT 1 FROM Pets p2
WHERE Pets.PetName = p2.PetName
AND Pets.PetType = p2.PetType
AND Pets.rowid > p2.rowid
);
Résultat :
PETID PETNAME PETTYPE 1 Wag Dog 4 Bark Dog 4 Bark Dog
La façon dont cela fonctionne est que chaque ligne d'une base de données Oracle a un rowid
pseudo-colonne qui renvoie l'adresse de la ligne. Le rowid
est un identifiant unique pour les lignes de la table, et généralement sa valeur identifie de manière unique une ligne dans la base de données. Cependant, il est important de noter que les lignes de différentes tables qui sont stockées ensemble dans le même cluster peuvent avoir le même rowid
.
L'un des avantages de l'exemple ci-dessus est que nous pouvons remplacer SELECT *
avec DELETE
afin de dédupliquer la table.
Option 6
Et enfin, voici une autre option qui utilise le rowid
pseudocolonne :
SELECT * FROM Pets
WHERE rowid > (
SELECT MIN(rowid) FROM Pets p2
WHERE Pets.PetName = p2.PetName
AND Pets.PetType = p2.PetType
);
Résultat :
PETID PETNAME PETTYPE 1 Wag Dog 4 Bark Dog 4 Bark Dog
Même résultat que l'exemple précédent.
Comme pour l'exemple précédent, nous pouvons remplacer SELECT *
avec DELETE
afin de supprimer les lignes en double de la table.