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

6 modi per selezionare righe duplicate in SQLite

Le seguenti query possono essere utilizzate per restituire righe duplicate in SQLite.

Qui, le righe duplicate contengono valori duplicati in tutte le colonne, inclusa la colonna ID.

Dati campione

Supponiamo di avere una tabella con i seguenti dati:

SELECT * FROM Pets;

Risultato:

PetId  PetName  PetType
-----  -------  -------
1      Wag      Dog    
1      Wag      Dog    
2      Scratch  Cat    
3      Tweet    Bird   
4      Bark     Dog    
4      Bark     Dog    
4      Bark     Dog    

Le prime due righe sono duplicate, così come le ultime tre righe. Questo perché tutte e tre le colonne contengono gli stessi valori in ogni riga duplicata.

Opzione 1

Possiamo usare la seguente query per vedere quante righe sono duplicate:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY PetId;

Risultato:

PetId  PetName  PetType  Count
-----  -------  -------  -----
1      Wag      Dog      2    
2      Scratch  Cat      1    
3      Tweet    Bird     1    
4      Bark     Dog      3    

Qui abbiamo raggruppato le righe per tutte le colonne e restituito il conteggio delle righe di ciascun gruppo. Questo ci dice se una riga è unica (con un conteggio pari a 1) o duplicata (con un conteggio maggiore di 1).

Possiamo ordinarlo per conteggio in ordine decrescente, in modo che le righe con il maggior numero di duplicati appaiano per prime:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY Count(*) DESC;

Risultato:

PetId  PetName  PetType  Count
-----  -------  -------  -----
4      Bark     Dog      3    
1      Wag      Dog      2    
2      Scratch  Cat      1    
3      Tweet    Bird     1    

Opzione 2

Se vogliamo solo le righe duplicate elencate, possiamo usare il HAVING clausola per restituire solo le righe con un conteggio maggiore di 1:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
HAVING COUNT(*) > 1
ORDER BY PetId;

Risultato:

PetId  PetName  PetType  Count
-----  -------  -------  -----
1      Wag      Dog      2    
4      Bark     Dog      3    

Opzione 3

Un'altra opzione è usare il ROW_NUMBER() funzione finestra:

SELECT 
    *, 
    ROW_NUMBER() OVER ( 
        PARTITION BY PetId, PetName, PetType 
        ORDER BY PetId, PetName, PetType
        ) AS Row_Number
FROM Pets;

Risultato:

PetId  PetName  PetType  Row_Number
-----  -------  -------  ----------
1      Wag      Dog      1         
1      Wag      Dog      2         
2      Scratch  Cat      1         
3      Tweet    Bird     1         
4      Bark     Dog      1         
4      Bark     Dog      2         
4      Bark     Dog      3         

Il PARTITION BY La clausola divide il set di risultati prodotto dal FROM clausola in partizioni a cui viene applicata la funzione. Quando specifichiamo le partizioni per il set di risultati, ogni partizione fa ricominciare la numerazione (cioè la numerazione inizierà da 1 per la prima riga in ogni partizione).

Opzione 4

Possiamo usare la query precedente come un'espressione di tabella comune:

WITH cte AS 
    (
        SELECT 
            *, 
            ROW_NUMBER() OVER ( 
                PARTITION BY PetId, PetName, PetType 
                ORDER BY PetId, PetName, PetType
                ) AS Row_Number
        FROM Pets
    )
SELECT * FROM cte WHERE Row_Number <> 1;

Risultato:

PetId  PetName  PetType  Row_Number
-----  -------  -------  ----------
1      Wag      Dog      2         
4      Bark     Dog      2         
4      Bark     Dog      3         

Questo restituisce solo le righe in eccesso dai duplicati corrispondenti. Quindi se ci sono due righe identiche, ne restituisce una. Se sono presenti tre righe identiche, ne restituisce due e così via.

Questa query può essere utile per mostrare quante righe verranno rimosse dalla tabella in un'operazione di deduplicazione. In alcuni altri DBMS (almeno in SQL Server), possiamo sostituire l'ultimo SELECT * con DELETE per eliminare le righe duplicate dalla tabella. Ma SQLite non ci permetterà di aggiornare il CTE in questo modo.

Fortunatamente, le prossime due opzioni possono essere modificate per eseguire un'eliminazione.

Opzione 5

Possiamo sfruttare rowid di SQLite :

SELECT * FROM Pets
WHERE EXISTS (
  SELECT 1 FROM Pets p2 
  WHERE Pets.PetName = p2.PetName
  AND Pets.PetType = p2.PetType
  AND Pets.rowid > p2.rowid
);

Risultato:

PetId  PetName  PetType
-----  -------  -------
1      Wag      Dog    
4      Bark     Dog    
4      Bark     Dog    

Come funziona? 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. Questo può essere rimosso se necessario, ma a meno che non sia stato rimosso esplicitamente, sarai in grado di sfruttarlo all'interno delle tue query.

Opzione 6

E infine, ecco un'altra opzione che utilizza rowid di SQLite :

SELECT * FROM Pets
WHERE rowid > (
  SELECT MIN(rowid) FROM Pets p2  
  WHERE Pets.PetName = p2.PetName
  AND Pets.PetType = p2.PetType
);

Risultato:

PetId  PetName  PetType
-----  -------  -------
1      Wag      Dog    
4      Bark     Dog    
4      Bark     Dog