SQLite
 sql >> Datenbank >  >> RDS >> SQLite

6 Möglichkeiten zum Löschen doppelter Zeilen mit einem Primärschlüssel in SQLite

Unten sind sechs Beispiele, die doppelte Zeilen aus einer Tabelle in SQLite löschen, wenn diese Zeilen einen Primärschlüssel oder eine eindeutige Bezeichnerspalte haben.

In diesen Fällen muss der Primärschlüssel beim Vergleich von Duplikaten ignoriert werden (aufgrund der Tatsache, dass Primärschlüssel per Definition doppelte Zeilen verhindern).

Beispieldaten

Unsere Beispiele verwenden die folgenden Daten:

SELECT * FROM Dogs; 

Ergebnis:

HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 2 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 6 Wag Johnson 7 Wag Johnson  

Wir können sehen, dass die ersten beiden Zeilen Duplikate enthalten, ebenso wie die letzten drei Zeilen.

Die DogId Spalte enthält eindeutige Werte (weil es der Primärschlüssel der Tabelle ist), und daher gibt es streng genommen keine Duplikate. In realen Situationen möchten Sie jedoch häufig Tabellen deduplizieren, die Primärschlüssel enthalten. Daher ignorieren wir in den folgenden Beispielen den Primärschlüssel und löschen Zeilen, die doppelte Werte in den verbleibenden Spalten enthalten.

Option 1

Hier ist unsere erste Option zum Deduplizieren der obigen Tabelle:

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

SELECT * FROM Dogs; 

Ergebnis:

HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 

Die Tabelle wurde wie erwartet dedupliziert.

Wir können alternativ den MAX() verwenden anstelle von MIN() Funktion, um zu ändern, welche Zeilen gelöscht werden. Ich werde dies im nächsten Beispiel tun.

Option 2

In diesem Beispiel (und den folgenden Beispielen) gehen wir davon aus, dass die Tabelle in ihrem ursprünglichen Zustand (mit den Duplikaten) wiederhergestellt wurde.

Hier ist eine weitere Abfrage, die doppelte Zeilen löscht und die verbleibenden Zeilen auswählt:

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; 

Ergebnis:

HundId Vorname Nachname ----- --------- -------- 2 Bark Smith 3 Woof Jones 4 Ruff Robinson7 Wag Johnson 

Die Tabelle wurde nun dedupliziert.

Beachten Sie, dass ich MAX() verwendet habe Funktion anstelle von MIN() die ich im vorherigen Beispiel verwendet habe. Wir können die Auswirkungen sehen, die dies auf den Deduplizierungsvorgang hat. Es hat verschiedene Zeilen aus der Tabelle gelöscht.

Option 3

Hier ist eine Option, die keine Verwendung von MIN() erfordert oder 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; 

Ergebnis:

HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 

Option 4

Hier ist eine weitere 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; 

Ergebnis:

HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 

Option 5

Standardmäßig hat jede Zeile in SQLite eine spezielle Spalte, die normalerweise als rowid bezeichnet wird , die diese Zeile innerhalb der Tabelle eindeutig identifiziert. Sofern es nicht ausdrücklich aus der Tabelle entfernt wurde, können Sie dies als eindeutige Kennung für jede Zeile verwenden. Diese Methode kann nützlich sein, wenn Sie aus irgendeinem Grund nicht auf den Primärschlüssel verweisen können (oder wenn die Tabelle keinen Primärschlüssel hat).

Wir können daher die rowid verwenden in unserer Abfrage anstelle der DogId Spalte:

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; 

Ergebnis:

HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 

Option 6

Und hier ist das andere Beispiel, aber mit rowid anstelle des Primärschlüssels:

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

SELECT * FROM Dogs; 

Ergebnis:

HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson