PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

7 Cara Menemukan Baris Duplikat di PostgreSQL sambil Mengabaikan Kunci Utama

Berikut adalah tujuh cara untuk mengembalikan baris duplikat di PostgreSQL ketika baris tersebut memiliki kunci utama atau kolom pengenal unik lainnya.

Ini berarti bahwa baris duplikat memiliki nilai yang sama persis di semua kolom dengan pengecualian kolom kunci utama/ID uniknya.

Contoh Data

Kami akan menggunakan data berikut untuk contoh kami:

SELECT * FROM Dogs;

Hasil:

 dogid | firstname | lastname 
-------+-----------+----------
     1 | Bark      | Smith
     2 | Bark      | Smith
     3 | Woof      | Jones
     4 | Ruff      | Robinson
     5 | Wag       | Johnson
     6 | Wag       | Johnson
     7 | Wag       | Johnson

Dua baris pertama adalah duplikat (kecuali untuk DogId kolom, yang merupakan kunci utama tabel, dan berisi nilai unik di semua baris). Tiga baris terakhir juga merupakan duplikat (kecuali untuk DogId kolom).

Kolom kunci utama memastikan bahwa tidak ada baris duplikat, yang merupakan praktik yang baik di RDBMS, karena kunci utama membantu menegakkan integritas data. Tetapi karena kunci utama mencegah baris duplikat, mereka berpotensi mengganggu kemampuan kita untuk menemukan duplikat.

Dalam tabel kami di atas, kolom kunci utama adalah angka yang bertambah, dan nilainya tidak memiliki arti dan tidak signifikan. Oleh karena itu, kita perlu mengabaikan baris itu jika ingin menemukan duplikat di kolom lain.

Opsi 1

Kita dapat menggunakan SQL GROUP BY klausa untuk mengelompokkan kolom menurut kolom signifikannya, lalu gunakan COUNT() fungsi untuk mengembalikan jumlah baris identik:

SELECT 
    FirstName, 
    LastName, 
    COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName;

Hasil:

 firstname | lastname | count 
-----------+----------+-------
 Ruff      | Robinson |     1
 Wag       | Johnson  |     3
 Woof      | Jones    |     1
 Bark      | Smith    |     2

Di sini kami mengecualikan kolom kunci utama dengan menghilangkannya dari kueri kami.

Hasilnya memberi tahu kita bahwa ada tiga baris berisi Wag Johnson dan dua baris berisi Bark Smith. Ini adalah duplikat (atau rangkap tiga dalam kasus Wag Johnson). Dua baris lainnya tidak memiliki duplikat.

Opsi 2

Kami dapat mengecualikan non-duplikat dari output dengan HAVING klausa:

SELECT 
    FirstName, 
    LastName, 
    COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName
HAVING COUNT(*) > 1;

Hasil:

 firstname | lastname | count 
-----------+----------+-------
 Wag       | Johnson  |     3
 Bark      | Smith    |     2

Opsi 3

Berikut adalah contoh pemeriksaan duplikat pada kolom gabungan. Dalam hal ini kita menggunakan CONCAT() fungsi untuk menggabungkan dua kolom kami, gunakan DISTINCT kata kunci untuk mendapatkan nilai yang berbeda, lalu gunakan COUNT() berfungsi untuk mengembalikan hitungan:

SELECT
    DISTINCT CONCAT(FirstName, ' ', LastName) AS DogName,
    COUNT(*) AS Count
FROM Dogs
GROUP BY CONCAT(FirstName, ' ', LastName);

Hasil:

    dogname    | count 
---------------+-------
 Wag Johnson   |     3
 Ruff Robinson |     1
 Woof Jones    |     1
 Bark Smith    |     2

Opsi 4

Sebagai alternatif, kita dapat menggunakan ROW_NUMBER() fungsi jendela:

SELECT 
    *,
    ROW_NUMBER() OVER ( 
        PARTITION BY FirstName, LastName 
        ORDER BY FirstName, LastName
        ) AS Row_Number
FROM Dogs;

Hasil:

 dogid | firstname | lastname | row_number 
-------+-----------+----------+------------
     1 | Bark      | Smith    |          1
     2 | Bark      | Smith    |          2
     4 | Ruff      | Robinson |          1
     5 | Wag       | Johnson  |          1
     6 | Wag       | Johnson  |          2
     7 | Wag       | Johnson  |          3
     3 | Woof      | Jones    |          1

Menggunakan PARTITION klausa menghasilkan kolom baru yang ditambahkan, dengan nomor baris yang bertambah setiap kali ada duplikat, tetapi disetel ulang lagi saat ada baris unik.

Dalam hal ini kami tidak mengelompokkan hasilnya, yang berarti kami dapat melihat setiap baris duplikat, termasuk kolom pengenal uniknya.

Opsi 5

Kami juga dapat menggunakan contoh sebelumnya sebagai ekspresi tabel umum dalam kueri yang lebih besar:

WITH cte AS 
    (
        SELECT 
            *,
            ROW_NUMBER() OVER ( 
                PARTITION BY FirstName, LastName 
                ORDER BY FirstName, LastName
                ) AS Row_Number
        FROM Dogs
    )
SELECT * FROM cte WHERE Row_Number <> 1;

Hasil:

 dogid | firstname | lastname | row_number 
-------+-----------+----------+------------
     2 | Bark      | Smith    |          2
     6 | Wag       | Johnson  |          2
     7 | Wag       | Johnson  |          3

Ini mengecualikan non-duplikat dari output, dan mengecualikan satu baris dari setiap duplikat dari output. Dengan kata lain, itu hanya menunjukkan kelebihan baris dari duplikat. Baris ini adalah kandidat utama untuk dihapus dalam operasi de-duping.

Opsi 6

Berikut cara yang lebih ringkas untuk mendapatkan hasil yang sama seperti contoh sebelumnya:

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

Hasil:

 dogid | firstname | lastname 
-------+-----------+----------
     6 | Wag       | Johnson
     2 | Bark      | Smith
     7 | Wag       | Johnson

Satu perbedaan antara contoh ini dan yang sebelumnya adalah bahwa contoh ini tidak memerlukan pembuatan nomor baris terpisah kita sendiri.

Opsi 7

Berikut ini opsi lain untuk mengembalikan baris duplikat di Postgres:

SELECT * 
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
);

Hasil:

 dogid | firstname | lastname | dogid | firstname | lastname 
-------+-----------+----------+-------+-----------+----------
     2 | Bark      | Smith    |     1 | Bark      | Smith
     7 | Wag       | Johnson  |     5 | Wag       | Johnson
     7 | Wag       | Johnson  |     6 | Wag       | Johnson

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Mengelola Database PostgreSQL Anda Dari ClusterControl CLI

  2. Formulir Django ke basis data kueri (model)

  3. Tabel sebagai argumen dari fungsi PostgreSQL

  4. Bekerja menuju Postgres-XL 9.5

  5. Normalisasikan subskrip larik untuk larik 1 dimensi sehingga dimulai dengan 1