Berikut adalah sebelas opsi untuk mengembalikan baris duplikat di SQLite ketika baris tersebut memiliki kunci utama atau kolom pengenal unik lainnya (tetapi Anda ingin mengabaikan kunci utama).
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 Robinson5 Wag Johnson 6 Wag Johnson 7 Wag JohnsonDua 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 untukDogId
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 menjalankan query dengan
GROUP BY
klausa untuk mengelompokkan kolom menurut kolom signifikannya, lalu gunakanCOUNT()
fungsi untuk mengembalikan jumlah baris identik:SELECT FirstName, LastName, COUNT(*) AS Count FROM Dogs GROUP BY FirstName, LastName ORDER BY Count DESC;
Hasil:
FirstName LastName Hitungan--------- -------- -----Wag Johnson 3 Bark Smith 2 Ruff Robinson 1 Woof Jones 1Di sini kami mengecualikan kolom kunci utama dengan menghilangkannya dari kueri kami. Kami juga mengurutkannya dengan hitungan 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 menggunakan
HAVING
klausa 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 Depan Nama Belakang Hitungan--------- -------- -----Wag Johnson 3 Bark Smith 2Opsi 3
Berikut adalah contoh pemeriksaan duplikat pada kolom gabungan. Dalam hal ini kami menggunakan
DISTINCT
kata kunci untuk mendapatkan nilai yang berbeda, lalu gunakanCOUNT()
berfungsi untuk mengembalikan hitungan:SELECT DISTINCT FirstName || ' ' || LastName AS DogName, COUNT(*) AS Count FROM Dogs GROUP BY FirstName || ' ' || LastName ORDER BY Count DESC;
Hasil:
Jumlah Nama Anjing------------- -----Wag Johnson 3 Bark Smith 2 Woof Jones 1 Ruff Robinson 1Opsi 4
Secara default, setiap baris di SQLite memiliki kolom khusus, biasanya disebut
rowid
, yang secara unik mengidentifikasi baris tersebut di dalam tabel. Kecuali telah dihapus secara eksplisit dari tabel, Anda dapat menggunakan ini sebagai pengenal unik untuk setiap baris.Oleh karena itu, kita dapat menggunakan
rowid
dalam pertanyaan kami: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 FirstName LastName----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag JohnsonKita bisa mengganti
SELECT *
denganDELETE
untuk melakukan operasi de-duping di atas meja.Perhatikan bahwa kita dapat menggunakan
DogId
kolom (kunci utama kami) alih-alihrowid
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 FirstName LastName----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag JohnsonSeperti contoh sebelumnya, kita dapat mengganti
SELECT *
denganDELETE
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 menggantirowid
dengan kolom kunci utama – dalam kasus kamiDogId
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 FirstName LastName----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag JohnsonOpsi 7
Dan inilah kueri lainnya dengan
rowid
diganti denganDogId
kolom:SELECT * FROM Dogs WHERE DogId > ( SELECT MIN(DogId) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName );
Hasil:
DogId FirstName LastName----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag JohnsonOpsi 8
Cara lain untuk melakukannya adalah dengan 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 Baris_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 1Menggunakan
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 *, 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 Baris_Number----- --------- -------- ----------2 Bark Smith 2 6 Wag Johnson 2 7 Wag Johnson 3Itu mengecualikan non-duplikat dari output, dan mengecualikan satu baris dari setiap duplikat dari output.
Opsi 10
Berikut cara lain 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----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag JohnsonOpsi 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 FirstName LastName DogId FirstName LastName----- --------- -------- ----- --------- ----- ---2 Bark Smith 1 Bark Smith 7 Gerak Johnson 5 Gerak Johnson 7 Gerak Johnson 6 Gerak Johnson