SQLite
 sql >> Teknologi Basis Data >  >> RDS >> SQLite

11 Cara Menemukan Baris Duplikat sambil Mengabaikan Kunci Utama di SQLite

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 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 menjalankan query dengan 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
ORDER BY Count DESC; 

Hasil:

FirstName LastName Hitungan--------- -------- -----Wag Johnson 3 Bark Smith 2 Ruff Robinson 1 Woof Jones 1 

Di 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 2 

Opsi 3

Berikut adalah contoh pemeriksaan 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:

Jumlah Nama Anjing------------- -----Wag Johnson 3 Bark Smith 2 Woof Jones 1 Ruff Robinson 1 

Opsi 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 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 FirstName LastName----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag 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 FirstName LastName----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag 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 FirstName LastName----- --------- --------2 Bark Smith 6 Wag Johnson 7 Wag Johnson 

Opsi 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 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 
            *,
            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 3 

Itu 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 Johnson 

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 FirstName LastName DogId FirstName LastName----- --------- -------- ----- --------- ----- ---2 Bark Smith 1 Bark Smith 7 Gerak Johnson 5 Gerak Johnson 7 Gerak Johnson 6 Gerak 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. Grup SQLite berdasarkan/hitung jam, hari, minggu, tahun

  2. Berapa batas variabel SQL yang dapat ditentukan dalam satu kueri execSQL?

  3. Android ListView:bagaimana cara menghindari kueri basis data di bindView ()? Perlu mengambil satu ke banyak data hubungan

  4. Bagaimana Replace() Bekerja di SQLite

  5. Realm Android Menangani Kunci Utama di Objek Relasional