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

6 modi per eliminare le righe duplicate che hanno una chiave primaria in SQLite

Di seguito sono riportati sei esempi che eliminano le righe duplicate da una tabella in SQLite quando tali righe hanno una chiave primaria o una colonna identificatore univoco.

In questi casi, la chiave primaria deve essere ignorata quando si confrontano i duplicati (perché le chiavi primarie impediscono per definizione le righe duplicate).

Dati campione

I nostri esempi utilizzano i seguenti dati:

SELECT * FROM Dogs;

Risultato:

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

Possiamo vedere che le prime due righe contengono duplicati, così come le ultime tre righe.

Il DogId colonna contiene valori univoci (perché è la chiave primaria della tabella) e quindi, in senso stretto, non ci sono duplicati. Ma nelle situazioni della vita reale, spesso vorrai deduplicare le tabelle che contengono chiavi primarie. Pertanto, negli esempi seguenti ignoriamo la chiave primaria ed eliminiamo le righe che contengono valori duplicati nelle colonne rimanenti.

Opzione 1

Ecco la nostra prima opzione per deduplicare la tabella sopra:

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

SELECT * FROM Dogs;

Risultato:

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

La tabella è stata deduplicata come previsto.

In alternativa possiamo usare il MAX() funzione invece di MIN() funzione per modificare le righe da eliminare. Lo farò nel prossimo esempio.

Opzione 2

In questo esempio (e negli esempi seguenti) assumeremo che la tabella sia stata ripristinata allo stato originale (con i duplicati).

Ecco un'altra query che elimina le righe duplicate e seleziona le righe rimanenti:

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;

Risultato:

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

Il tavolo è stato ora deduplicato.

Nota che ho usato MAX() funzione invece di MIN() che ho usato nell'esempio precedente. Possiamo vedere l'effetto che questo ha sull'operazione di de-duping. Ha eliminato diverse righe dalla tabella.

Opzione 3

Ecco un'opzione che non richiede l'uso di MIN() o 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;

Risultato:

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

Opzione 4

Ecco un'altra opzione:

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

SELECT * FROM Dogs;

Risultato:

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

Opzione 5

Per impostazione predefinita, ogni riga in SQLite ha una colonna speciale, solitamente chiamata rowid , che identifica in modo univoco quella riga all'interno della tabella. A meno che non sia stato esplicitamente rimosso dalla tabella, puoi usarlo come identificatore univoco per ogni riga. Questo metodo potrebbe essere utile se per qualche motivo non sei in grado di fare riferimento alla chiave primaria (o se la tabella non ha una chiave primaria).

Possiamo quindi utilizzare il rowid nella nostra query invece di DogId colonna:

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;

Risultato:

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

Opzione 6

Ed ecco l'altro esempio, ma con rowid invece della chiave primaria:

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

SELECT * FROM Dogs;

Risultato:

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