PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

4 maneiras de selecionar linhas duplicadas no PostgreSQL


Se você tiver uma tabela com linhas duplicadas no PostgreSQL, poderá usar qualquer uma das seguintes consultas para retornar as linhas duplicadas.

Dados de amostra


Suponha que temos uma tabela com os seguintes dados:
SELECT * FROM Pets;

Resultado:
 petid | petname | pettype 
-------+---------+---------
     1 | Wag     | Dog
     1 | Wag     | Dog
     2 | Scratch | Cat
     3 | Tweet   | Bird
     4 | Bark    | Dog
     4 | Bark    | Dog
     4 | Bark    | Dog

As duas primeiras linhas são duplicadas e as três últimas linhas são duplicadas. Isso porque todas as três colunas contêm os mesmos valores em cada linha duplicada.

Opção 1


Podemos usar a seguinte consulta para ver quantas linhas são duplicadas:
SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY PetId;

Resultado:
 petid | petname | pettype | Count 
-------+---------+---------+-------
     1 | Wag     | Dog     |     2
     2 | Scratch | Cat     |     1
     3 | Tweet   | Bird    |     1
     4 | Bark    | Dog     |     3

Alternativamente, podemos ordená-lo por contagem em ordem decrescente, para que as linhas com mais duplicatas apareçam primeiro:
SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY Count(*) DESC;

Resultado:
 petid | petname | pettype | Count 
-------+---------+---------+-------
     4 | Bark    | Dog     |     3
     1 | Wag     | Dog     |     2
     2 | Scratch | Cat     |     1
     3 | Tweet   | Bird    |     1

Opção 2


Podemos usar o HAVING cláusula se quisermos apenas as linhas duplicadas listadas:
SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
HAVING COUNT(*) > 1
ORDER BY PetId;

Resultado:
 petid | petname | pettype | Count 
-------+---------+---------+-------
     1 | Wag     | Dog     |     2
     4 | Bark    | Dog     |     3

Opção 3


Outra opção é usar o ROW_NUMBER() do Postgres função da janela:
SELECT 
    *, 
    ROW_NUMBER() OVER ( 
        PARTITION BY PetId, PetName, PetType 
        ORDER BY PetId, PetName, PetType
        ) AS Row_Number
FROM Pets;

Resultado:
 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

A PARTITION BY cláusula divide o conjunto de resultados produzido pelo FROM cláusula em partições às quais a função é aplicada. Quando especificamos partições para o conjunto de resultados, cada partição faz com que a numeração comece novamente (ou seja, a numeração começará em 1 para a primeira linha de cada partição).

Opção 4


Podemos usar a consulta acima como uma expressão de tabela comum para retornar apenas as linhas excedentes das duplicatas correspondentes:
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;

Resultado:
 petid | petname | pettype | row_number 
-------+---------+---------+------------
     1 | Wag     | Dog     |          2
     4 | Bark    | Dog     |          2
     4 | Bark    | Dog     |          3