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

6 façons de supprimer les lignes en double qui ont une clé primaire dans Oracle

Voici quelques options pour supprimer les lignes en double d'une table dans Oracle Database lorsque ces lignes ont une clé primaire ou une colonne d'identifiant unique.

Dans de tels cas, la clé primaire doit être ignorée lors de la comparaison de lignes en double (en raison du fait que les clés primaires contiennent des valeurs uniques).

Exemple de données

Nos exemples utilisent les données suivantes :

SELECT * FROM Dogs;

Résultat :

DOGID PRÉNOM NOM
1 Aboiement Smith
2 Aboiement Smith
3 Ouaf Jones
4 Ruff Robinson
5 Wag Johnson
6 Wag Johnson
7 Wag Johnson

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

Le DogId La colonne contient des valeurs uniques (parce que c'est la clé primaire de la table), mais nous ignorons cette colonne lors de la comparaison des doublons. Vous pouvez souvent avoir besoin de dédupliquer des tables contenant des clés primaires, et les exemples suivants peuvent donc être utilisés pour faire exactement cela.

Option 1

Voici notre première option pour dédupliquer le tableau ci-dessus :

DELETE FROM Dogs 
WHERE DogId IN (
    SELECT DogId FROM Dogs 
    MINUS SELECT MIN(DogId) FROM Dogs 
    GROUP BY FirstName, LastName
    );

SELECT * FROM Dogs;

Résultat :

DOGID PRÉNOM NOM
1 Aboiement Smith
3 Ouaf Jones
4 Ruff Robinson
5 Wag Johnson

Les doublons ont été supprimés (mais il reste une ligne de chaque doublon).

Nous pouvons alternativement utiliser le MAX() fonction au lieu de MIN() fonction pour changer les lignes à supprimer.

Option 2

Dans cet exemple (et les exemples suivants), nous supposerons que la table a été restaurée dans son état d'origine (avec les doublons).

Voici un autre exemple qui dédouble la table, puis sélectionne les lignes restantes :

DELETE FROM Dogs WHERE DogId IN (
    SELECT d2.DogId 
    FROM Dogs d1, Dogs d2 
    WHERE d1.FirstName = d2.FirstName 
    AND d1.LastName = d2.LastName 
    AND d1.DogId <> d2.DogId 
    AND d1.DogId=( 
        SELECT MAX(DogId) 
        FROM Dogs d3 
        WHERE d3.FirstName = d1.FirstName 
        AND d3.LastName = d1.LastName
    )
);

SELECT * FROM Dogs;

Résultat :

DOGID PRÉNOM NOM
2 Aboiement Smith
3 Ouaf Jones
4 Ruff Robinson
7 Wag Johnson

Notez que j'ai utilisé le MAX() fonction au lieu de MIN() que j'ai utilisé dans l'exemple précédent. Nous pouvons voir l'effet que cela a sur l'opération de dédoublement. Il a supprimé différentes lignes de la table.

Option 3

Voici une option qui ne nécessite pas l'utilisation de MIN() ou MAX() :

DELETE FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.DogId > d2.DogId
);

SELECT * FROM Dogs;

Résultat :

DOGID PRÉNOM NOM
1 Aboiement Smith
3 Ouaf Jones
4 Ruff Robinson
5 Wag Johnson

Option 4

Voici une autre option :

DELETE FROM Dogs
WHERE DogId > (
  SELECT MIN(DogId) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
);

SELECT * FROM Dogs;

Résultat :

DOGID PRÉNOM NOM
1 Aboiement Smith
3 Ouaf Jones
4 Ruff Robinson
5 Wag Johnson

Option 5

Chaque ligne dans 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 (bien qu'il soit 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 ).

On peut donc utiliser le rowid dans notre requête au lieu de DogId colonne :

DELETE FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.rowid > d2.rowid
);

SELECT * FROM Dogs;

Résultat :

DOGID PRÉNOM NOM
1 Aboiement Smith
3 Ouaf Jones
4 Ruff Robinson
5 Wag Johnson

Bien que cet exemple puisse sembler légèrement superflu, étant donné que nous avons déjà une colonne de clé primaire, il peut y avoir des cas où vous préférez utiliser le rowid . Le rowid peut être utile si vous ne pouvez pas utiliser la colonne de clé primaire pour une raison quelconque, ou si la table n'a pas de clé primaire. De plus, la documentation d'Oracle mentionne que rowid les valeurs sont le moyen le plus rapide d'accéder à une seule ligne.

Option 6

Et voici l'autre exemple, mais avec rowid au lieu de la clé primaire :

DELETE FROM Dogs
WHERE rowid > (
  SELECT MIN(rowid) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
);

SELECT * FROM Dogs;

Résultat :

DOGID PRÉNOM NOM
1 Aboiement Smith
3 Ouaf Jones
4 Ruff Robinson
5 Wag Johnson