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

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

Vous trouverez ci-dessous six exemples qui suppriment les lignes en double d'une table dans SQLite lorsque ces lignes ont une clé primaire ou une colonne d'identifiant unique.

Dans ces cas, la clé primaire doit être ignorée lors de la comparaison des doublons (en raison du fait que les clés primaires empêchent les lignes en double par définition).

Exemple de données

Nos exemples utilisent les données suivantes :

SELECT * FROM Dogs; 

Résultat :

DogId FirstName LastName----- --------- --------1 Bark Smith 2 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 6 Wag Johnson 7 Wag Johnson  

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

Le DogId colonne contient des valeurs uniques (parce que c'est la clé primaire de la table), et donc, à proprement parler, il n'y a pas de doublons. Mais dans des situations réelles, vous souhaiterez souvent dédupliquer des tables contenant des clés primaires. Par conséquent, dans les exemples suivants, nous ignorons la clé primaire et supprimons les lignes contenant des valeurs en double dans les colonnes restantes.

Option 1

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

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

SELECT * FROM Dogs; 

Résultat :

DogId FirstName LastName----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 

La table a été dédupliquée comme prévu.

Nous pouvons alternativement utiliser le MAX() fonction au lieu de MIN() fonction pour modifier les lignes à supprimer. Je vais le faire dans l'exemple suivant.

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 une autre requête qui supprime les lignes en double et 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 FirstName LastName----- --------- --------2 Bark Smith 3 Woof Jones 4 Ruff Robinson7 Wag Johnson 

La table a maintenant été dédupliquée.

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 du tableau.

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 FirstName LastName----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 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 FirstName LastName----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 

Option 5

Par défaut, chaque ligne dans SQLite a une colonne spéciale, généralement appelée rowid , qui identifie de manière unique cette ligne dans le tableau. À moins qu'il n'ait été explicitement supprimé de la table, vous pouvez l'utiliser comme identifiant unique pour chaque ligne. Cette méthode peut être utile si vous ne parvenez pas à référencer la clé primaire pour une raison quelconque (ou si la table n'a pas de clé primaire).

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 FirstName LastName----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 

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 FirstName LastName----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson