sql >> Databasteknik >  >> RDS >> SQLite

6 sätt att ta bort dubbletter av rader som har en primärnyckel i SQLite

Nedan finns sex exempel som tar bort dubbletter av rader från en tabell i SQLite när dessa rader har en primärnyckel eller unik identifierarkolumn.

I dessa fall måste primärnyckeln ignoreras vid jämförelse av dubbletter (beroende på det faktum att primärnycklar förhindrar dubbletter av rader per definition).

Exempeldata

Våra exempel använder följande data:

SELECT * FROM Dogs; 

Resultat:

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

Vi kan se att de två första raderna innehåller dubbletter, liksom de tre sista raderna.

DogId kolumnen innehåller unika värden (eftersom det är tabellens primärnyckel), och därför finns det strängt taget inga dubbletter. Men i verkliga situationer vill du ofta de-dupera tabeller som innehåller primärnycklar. Därför ignorerar vi i följande exempel primärnyckeln och tar bort rader som innehåller dubbletter av värden över de återstående kolumnerna.

Alternativ 1

Här är vårt första alternativ för att dedupera tabellen ovan:

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

Tabellen har avduperats som förväntat.

Vi kan alternativt använda MAX() funktion istället för MIN() funktion för att ändra vilka rader som tas bort. Jag ska göra detta i nästa exempel.

Alternativ 2

I det här exemplet (och följande exempel) antar vi att tabellen har återställts till sitt ursprungliga tillstånd (med dubbletter).

Här är en annan fråga som tar bort dubbletter av rader och väljer de återstående raderna:

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 Efternamn----- ---------- --------2 Bark Smith 3 Woof Jones 4 Ruff Robinson7 Wag Johnson 

Tabellen har nu avduperats.

Lägg märke till att jag använde MAX() funktion istället för MIN() som jag använde i föregående exempel. Vi kan se vilken inverkan detta har på de-dupingverksamheten. Den raderade olika rader från tabellen.

Alternativ 3

Här är ett alternativ som inte kräver användning av 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 Efternamn----- ---------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 

Alternativ 4

Här är ett annat alternativ:

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

Alternativ 5

Som standard har varje rad i SQLite en speciell kolumn, vanligtvis kallad rowid , som unikt identifierar den raden i tabellen. Om den inte uttryckligen har tagits bort från tabellen kan du använda den som en unik identifierare för varje rad. Den här metoden kan vara användbar om du av någon anledning inte kan referera till primärnyckeln (eller om tabellen inte har en primärnyckel).

Vi kan därför använda rowid i vår fråga istället för DogId kolumn:

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

Alternativ 6

Och här är det andra exemplet, men med rowid istället för primärnyckeln:

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

  1. Beräkna en löpande summa i MySQL

  2. Snabbast kontrollera om rad finns i PostgreSQL

  3. Fördelar med NoSQL-databaser – Allt du behöver veta

  4. Hur man åtgärdar "Begäran COMMIT TRANSACTION har ingen motsvarande BEGIN TRANSACTION" i SQL Server