PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

4 modi per selezionare righe duplicate in PostgreSQL

Se hai una tabella con righe duplicate in PostgreSQL, puoi utilizzare una delle seguenti query per restituire le righe duplicate.

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 e le ultime tre righe sono duplicate. 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

Possiamo in alternativa 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

Possiamo usare il HAVING clausola se vogliamo solo le righe duplicate elencate:

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 è utilizzare ROW_NUMBER() di Postgres 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 utilizzare la query precedente come un'espressione di tabella comune per restituire solo le righe in eccesso dai duplicati corrispondenti:

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