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