sql >> Database >  >> RDS >> SQLite

6 manieren om dubbele rijen met een primaire sleutel in SQLite te verwijderen

Hieronder staan ​​zes voorbeelden die dubbele rijen verwijderen uit een tabel in SQLite wanneer die rijen een primaire sleutel of een unieke id-kolom hebben.

In deze gevallen moet de primaire sleutel worden genegeerd bij het vergelijken van duplicaten (omdat primaire sleutels per definitie dubbele rijen voorkomen).

Voorbeeldgegevens

Onze voorbeelden gebruiken de volgende gegevens:

SELECT * FROM Dogs;

Resultaat:

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

We kunnen zien dat de eerste twee rijen duplicaten bevatten, net als de laatste drie rijen.

De DogId kolom bevat unieke waarden (omdat het de primaire sleutel van de tabel is) en daarom zijn er strikt genomen geen duplicaten. Maar in de praktijk wil je vaak tabellen met primaire sleutels ontdubbelen. Daarom negeren we in de volgende voorbeelden de primaire sleutel en verwijderen we rijen die dubbele waarden bevatten in de overige kolommen.

Optie 1

Dit is onze eerste optie om de bovenstaande tabel te ontdubbelen:

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

SELECT * FROM Dogs;

Resultaat:

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

De tafel is zoals verwacht ontdubbeld.

We kunnen ook de MAX() . gebruiken functie in plaats van de MIN() functie om te wijzigen welke rijen worden verwijderd. Ik doe dit in het volgende voorbeeld.

Optie 2

In dit voorbeeld (en de volgende voorbeelden) gaan we ervan uit dat de tabel in de oorspronkelijke staat is hersteld (met de duplicaten).

Hier is nog een zoekopdracht die dubbele rijen verwijdert en de resterende rijen selecteert:

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;

Resultaat:

DogId  FirstName  LastName
-----  ---------  --------
2      Bark       Smith   
3      Woof       Jones   
4      Ruff       Robinson
7      Wag        Johnson 

De tafel is nu ontdubbeld.

Merk op dat ik de MAX() . heb gebruikt functie in plaats van MIN() die ik in het vorige voorbeeld heb gebruikt. We kunnen zien welk effect dit heeft op de ontdubbelingsoperatie. Het heeft verschillende rijen uit de tabel verwijderd.

Optie 3

Hier is een optie die het gebruik van MIN() . niet vereist of 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;

Resultaat:

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

Optie 4

Hier is nog een optie:

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

SELECT * FROM Dogs;

Resultaat:

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

Optie 5

Standaard heeft elke rij in SQLite een speciale kolom, meestal de rowid , die die rij in de tabel op unieke wijze identificeert. Tenzij het expliciet uit de tabel is verwijderd, kunt u dit gebruiken als een unieke id voor elke rij. Deze methode kan handig zijn als u om de een of andere reden niet naar de primaire sleutel kunt verwijzen (of als de tabel geen primaire sleutel heeft).

We kunnen daarom de rowid . gebruiken in onze zoekopdracht in plaats van de DogId kolom:

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;

Resultaat:

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

Optie 6

En hier is het andere voorbeeld, maar met rowid in plaats van de primaire sleutel:

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

SELECT * FROM Dogs;

Resultaat:

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

  1. php-datum converteren naar mysql-formaat

  2. Hoe te repareren "Er kan slechts één uitdrukking worden opgegeven in de selectielijst ..." in SQL Server

  3. Een web-app maken vanaf nul met Python Flask en MySQL:deel 3

  4. Top MySQL-blogs en websites voor databasebeheerders