Berikut adalah beberapa opsi untuk menghapus baris duplikat dari tabel di Oracle Database ketika baris tersebut memiliki kunci utama atau kolom pengenal unik.
Dalam kasus seperti itu, kunci utama harus diabaikan saat membandingkan baris duplikat (karena fakta bahwa kunci utama memiliki nilai unik).
Contoh Data
Contoh kami menggunakan data berikut:
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 |
Kita dapat melihat bahwa dua baris pertama adalah duplikat, seperti halnya tiga baris terakhir.
DogId
kolom memiliki nilai unik (karena ini adalah kunci utama tabel), tetapi kami mengabaikan kolom tersebut saat membandingkan duplikat. Anda mungkin sering mendapati diri Anda perlu melakukan de-dupe tabel yang berisi kunci utama, sehingga contoh berikut dapat digunakan untuk melakukan hal itu.
Opsi 1
Inilah opsi pertama kami untuk menghilangkan pemalsuan tabel di atas:
DELETE FROM Dogs
WHERE DogId IN (
SELECT DogId FROM Dogs
MINUS SELECT MIN(DogId) FROM Dogs
GROUP BY FirstName, LastName
);
SELECT * FROM Dogs;
Hasil:
DOGID | NAMA PERTAMA | NAMA TERAKHIR |
---|---|---|
1 | Kulit | Smith |
3 | Guk | Jones |
4 | Ruff | Robinson |
5 | Goyang | Johnson |
Duplikat telah dihapus (tetapi satu baris dari setiap duplikat tetap ada).
Sebagai alternatif, kita dapat menggunakan MAX()
fungsi alih-alih MIN()
berfungsi untuk mengubah baris mana yang dihapus.
Opsi 2
Dalam contoh ini (dan contoh berikut) kami akan menganggap bahwa tabel telah dikembalikan ke keadaan semula (dengan duplikat).
Berikut adalah contoh lain yang menghilangkan penipuan tabel dan kemudian memilih baris yang tersisa:
DELETE FROM Dogs WHERE DogId IN (
SELECT d2.DogId
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
)
);
SELECT * FROM Dogs;
Hasil:
DOGID | NAMA PERTAMA | NAMA TERAKHIR |
---|---|---|
2 | Kulit | Smith |
3 | Guk | Jones |
4 | Ruff | Robinson |
7 | Goyang | Johnson |
Perhatikan bahwa saya menggunakan MAX()
fungsi alih-alih MIN()
yang saya gunakan pada contoh sebelumnya. Kita dapat melihat pengaruhnya terhadap operasi de-duping. Itu menghapus baris yang berbeda dari tabel.
Opsi 3
Berikut adalah opsi yang tidak memerlukan penggunaan MIN()
atau MAX()
:
DELETE FROM Dogs
WHERE EXISTS (
SELECT 1 FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
AND Dogs.DogId > d2.DogId
);
SELECT * FROM Dogs;
Hasil:
DOGID | NAMA PERTAMA | NAMA TERAKHIR |
---|---|---|
1 | Kulit | Smith |
3 | Guk | Jones |
4 | Ruff | Robinson |
5 | Goyang | Johnson |
Opsi 4
Ini opsi lain:
DELETE FROM Dogs
WHERE DogId > (
SELECT MIN(DogId) FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
);
SELECT * FROM Dogs;
Hasil:
DOGID | NAMA PERTAMA | NAMA TERAKHIR |
---|---|---|
1 | Kulit | Smith |
3 | Guk | Jones |
4 | Ruff | Robinson |
5 | Goyang | Johnson |
Opsi 5
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
).
Oleh karena itu, kita dapat menggunakan rowid
dalam kueri kami alih-alih DogId
kolom:
DELETE FROM Dogs
WHERE EXISTS (
SELECT 1 FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
AND Dogs.rowid > d2.rowid
);
SELECT * FROM Dogs;
Hasil:
DOGID | NAMA PERTAMA | NAMA TERAKHIR |
---|---|---|
1 | Kulit | Smith |
3 | Guk | Jones |
4 | Ruff | Robinson |
5 | Goyang | Johnson |
Meskipun contoh ini mungkin tampak sedikit berlebihan, mengingat kita sudah memiliki kolom kunci utama, mungkin ada contoh di mana Anda lebih suka menggunakan rowid
. rowid
dapat berguna jika Anda tidak dapat menggunakan kolom kunci utama karena alasan tertentu, atau jika tabel tidak memiliki kunci utama. Juga, dokumentasi Oracle menyebutkan bahwa rowid
nilai adalah cara tercepat untuk mengakses satu baris.
Opsi 6
Dan inilah contoh lainnya, tetapi dengan rowid
alih-alih kunci utama:
DELETE FROM Dogs
WHERE rowid > (
SELECT MIN(rowid) FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
);
SELECT * FROM Dogs;
Hasil:
DOGID | NAMA PERTAMA | NAMA TERAKHIR |
---|---|---|
1 | Kulit | Smith |
3 | Guk | Jones |
4 | Ruff | Robinson |
5 | Goyang | Johnson |