sql >> Database teknologi >  >> RDS >> SQLite

6 måder at slette duplikerede rækker, der har en primær nøgle i SQLite

Nedenfor er seks eksempler, der sletter dublerede rækker fra en tabel i SQLite, når disse rækker har en primær nøgle eller en unik identifikatorkolonne.

I disse tilfælde skal den primære nøgle ignoreres, når dubletter sammenlignes (på grund af det faktum, at primærnøgler pr. definition forhindrer duplikerede rækker).

Eksempeldata

Vores eksempler bruger følgende data:

SELECT * FROM Dogs; 

Resultat:

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

Vi kan se, at de første to rækker indeholder dubletter, ligesom de sidste tre rækker.

DogId kolonne indeholder unikke værdier (fordi det er tabellens primære nøgle), og derfor er der strengt taget ingen dubletter. Men i virkelige situationer vil du ofte ønske at de-dupere tabeller, der indeholder primærnøgler. Derfor ignorerer vi i de følgende eksempler den primære nøgle og sletter rækker, der indeholder duplikerede værdier på tværs af de resterende kolonner.

Valgmulighed 1

Her er vores første mulighed for at de-dupere ovenstående tabel:

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

SELECT * FROM Dogs; 

Resultat:

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

Tabellen er blevet de-duperet som forventet.

Vi kan alternativt bruge MAX() funktion i stedet for MIN() funktion til at ændre, hvilke rækker der slettes. Det vil jeg gøre i det næste eksempel.

Valgmulighed 2

I dette eksempel (og de følgende eksempler) antager vi, at tabellen er blevet gendannet til sin oprindelige tilstand (med dubletterne).

Her er en anden forespørgsel, der sletter dublerede rækker og vælger de resterende rækker:

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; 

Resultat:

DogId FirstName Efternavn----- ---------- --------2 Bark Smith 3 Woof Jones 4 Ruff Robinson7 Wag Johnson 

Tabellen er nu blevet de-duperet.

Bemærk, at jeg brugte MAX() funktion i stedet for MIN() som jeg brugte i det forrige eksempel. Vi kan se, hvilken indflydelse dette har på de-duping-operationen. Den slettede forskellige rækker fra tabellen.

Valgmulighed 3

Her er en mulighed, der ikke kræver brug af MIN() eller 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; 

Resultat:

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

Valgmulighed 4

Her er en anden mulighed:

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

SELECT * FROM Dogs; 

Resultat:

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

Valgmulighed 5

Som standard har hver række i SQLite en speciel kolonne, normalt kaldet rowid , der entydigt identificerer den pågældende række i tabellen. Medmindre det eksplicit er blevet fjernet fra tabellen, kan du bruge dette som en unik identifikator for hver række. Denne metode kan være nyttig, hvis du af en eller anden grund ikke er i stand til at referere til den primære nøgle (eller hvis tabellen ikke har en primær nøgle).

Vi kan derfor bruge rowid i vores forespørgsel i stedet for DogId kolonne:

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; 

Resultat:

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

Valgmulighed 6

Og her er det andet eksempel, men med rowid i stedet for den primære nøgle:

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

SELECT * FROM Dogs; 

Resultat:

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

  1. Hvordan kan jeg bruge regex til at opdele en streng ved at bruge en streng som afgrænsning?

  2. PGTune-alternativer - ClusterControl PostgreSQL-konfiguration

  3. Hvordan indsætter/opdaterer man større datastørrelser i Oracle-tabellerne?

  4. MySQL Quick Tip:Brug af LENGTH og TRIM funktionen