Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

11 Cara Menemukan Baris Duplikat yang memiliki Kunci Utama di Oracle

Berikut adalah sebelas opsi untuk mengembalikan baris duplikat di Oracle Database ketika baris tersebut memiliki kunci utama atau kolom pengenal unik lainnya dan Anda ingin mengabaikannya.

Contoh Data

Kami akan menggunakan data berikut untuk contoh kami:

SELECT * FROM Dogs;

Hasil:

DOGID NAMA PERTAMA NAMA TERAKHIR
1 Kulit Smith
2 Kulit Smith
3 Guk Jones
4 Ruff Robinson
5 Goyang Johnson
6 Goyang Johnson
7 Goyang Johnson

Dua baris pertama adalah duplikat dan tiga baris terakhir adalah duplikat. Baris duplikat memiliki nilai yang sama persis di semua kolom dengan pengecualian kolom kunci utama/ID uniknya.

Kolom kunci utama memastikan bahwa tidak ada baris duplikat, yang merupakan praktik yang baik di RDBMS, karena kunci utama membantu menegakkan integritas data. Tetapi fakta bahwa kunci utama berisi nilai unik berarti bahwa kita perlu mengabaikan kolom tersebut saat mencari duplikat.

Dalam tabel kami di atas, kolom kunci utama adalah angka yang bertambah, dan nilainya tidak memiliki arti dan tidak signifikan. Oleh karena itu, kami dapat mengabaikan data kolom tersebut saat mencari duplikat.

Opsi 1

Inilah opsi pertama kami untuk mengembalikan duplikat:

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

Hasil:

NAMA PERTAMA NAMA TERAKHIR COUNT
Bergoyang Johnson 3
Kulit Smith 2
Ruff Robinson 1
Guk Jones 1

Di sini kami membuat kueri dengan GROUP BY klausa sehingga output dikelompokkan berdasarkan kolom yang relevan. Kami juga menggunakan COUNT() berfungsi untuk mengembalikan jumlah baris yang identik. Dan kami memesannya dengan menghitung dalam urutan menurun sehingga duplikat muncul lebih dulu.

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

Kita dapat menambahkan HAVING klausa ke contoh kami sebelumnya untuk mengecualikan non-duplikat dari output:

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

Hasil:

NAMA PERTAMA NAMA TERAKHIR COUNT
Bergoyang Johnson 3
Kulit Smith 2

Opsi 3

Kami juga dapat memeriksa duplikat pada kolom gabungan. Dalam hal ini kami menggunakan DISTINCT kata kunci untuk mendapatkan nilai yang berbeda, lalu gunakan COUNT() berfungsi untuk mengembalikan hitungan:

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

Hasil:

NAMA ANJING COUNT
Wag Johnson 3
Bark Smith 2
Ruff Robinson 1
Guk Jones 1

Opsi 4

Setiap baris di Oracle memiliki rowid pseudocolumn yang mengembalikan alamat baris. rowid adalah pengidentifikasi unik untuk baris dalam tabel, dan biasanya nilainya secara unik mengidentifikasi baris dalam database (walaupun penting untuk dicatat bahwa baris dalam tabel berbeda yang disimpan bersama dalam cluster yang sama dapat memiliki rowid ).

Bagaimanapun, kita dapat membuat kueri yang menggunakan rowid jika kita mau:

SELECT * FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.rowid > d2.rowid
);

Hasil:

DOGID NAMA PERTAMA NAMA TERAKHIR
2 Kulit Smith
6 Goyang Johnson
7 Goyang Johnson

Kita bisa mengganti SELECT * dengan DELETE untuk melakukan operasi de-duping di atas meja.

Perhatikan bahwa kita dapat menggunakan DogId kolom (kunci utama kami) alih-alih rowid jika kita ingin. Yang mengatakan, rowid dapat berguna jika Anda tidak dapat menggunakan kolom kunci utama karena alasan tertentu, atau jika tabel tidak memiliki kunci utama.

Opsi 5

Berikut kueri lain yang menggunakan rowid :

SELECT * FROM Dogs
WHERE rowid > (
  SELECT MIN(rowid) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
);

Hasil:

DOGID NAMA PERTAMA NAMA TERAKHIR
2 Kulit Smith
6 Goyang Johnson
7 Goyang Johnson

Seperti contoh sebelumnya, kita dapat mengganti SELECT * dengan DELETE untuk menghapus baris duplikat.

Opsi 6

Dua rowid opsi di atas sangat bagus jika Anda benar-benar harus mengabaikan kunci utama dalam kueri Anda (atau jika Anda tidak memiliki kolom kunci utama sama sekali). Namun seperti yang disebutkan, masih ada opsi untuk mengganti rowid dengan kolom kunci utama – dalam kasus kami DogId kolom:

SELECT * FROM Dogs
WHERE EXISTS (
  SELECT 1 FROM Dogs d2 
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
  AND Dogs.DogId > d2.DogId
);

Hasil:

DOGID NAMA PERTAMA NAMA TERAKHIR
2 Kulit Smith
6 Goyang Johnson
7 Goyang Johnson

Opsi 7

Dan inilah kueri lainnya dengan rowid diganti dengan DogId kolom:

SELECT * FROM Dogs
WHERE DogId > (
  SELECT MIN(DogId) FROM Dogs d2  
  WHERE Dogs.FirstName = d2.FirstName
  AND Dogs.LastName = d2.LastName
);

Hasil:

DOGID NAMA PERTAMA NAMA TERAKHIR
2 Kulit Smith
6 Goyang Johnson
7 Goyang Johnson

Opsi 8

Cara lain untuk menemukan duplikat adalah dengan menggunakan ROW_NUMBER() fungsi jendela:

SELECT 
    DogId,
    FirstName,
    LastName,
    ROW_NUMBER() OVER ( 
        PARTITION BY FirstName, LastName 
        ORDER BY FirstName, LastName
        ) AS row_num
FROM Dogs;

Hasil:

DOGID NAMA PERTAMA NAMA TERAKHIR ROW_NUM
1 Kulit Smith 1
2 Kulit Smith 2
4 Ruff Robinson 1
7 Goyang Johnson 1
5 Goyang Johnson 2
6 Goyang Johnson 3
3 Guk 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 9

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

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

Hasil:

DOGID NAMA PERTAMA NAMA TERAKHIR ROW_NUM
2 Kulit Smith 2
5 Goyang Johnson 2
6 Goyang Johnson 3

Kueri tersebut mengecualikan non-duplikat dari keluaran, dan mengecualikan satu baris dari setiap duplikat dari keluaran.

Opsi 10

Berikut cara lain untuk mendapatkan hasil yang sama seperti contoh sebelumnya:

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

Hasil:

DOGID NAMA PERTAMA NAMA TERAKHIR
2 Kulit Smith
6 Goyang Johnson
7 Goyang Johnson

Contoh ini menggunakan MINUS Oracle operator, yang hanya mengembalikan baris unik yang dikembalikan oleh kueri pertama tetapi tidak oleh yang kedua.

MINUS operator mirip dengan EXCEPT operator di DBMS lain, seperti SQL Server, MariaDB, PostgreSQL, dan SQLite.

Opsi 11

Berikut ini opsi lain untuk memilih duplikat dari tabel kami:

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 NAMA PERTAMA NAMA TERAKHIR DOGID NAMA PERTAMA NAMA TERAKHIR
2 Kulit Smith 1 Kulit Smith
7 Goyang Johnson 5 Goyang Johnson
7 Goyang Johnson 6 Goyang 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. Membangun daftar nilai yang dipisahkan koma dalam pernyataan Oracle SQL

  2. Cara membuat pengguna di Oracle 11g dan memberikan izin

  3. Cara Mengembalikan Jumlah Detik Lewat Tengah Malam di Oracle Database

  4. C# memanggil fungsi tersimpan oracle

  5. InMemory DUPLICATE Kebingungan di Oracle RAC