Sqlserver
 sql >> Teknologi Basis Data >  >> RDS >> Sqlserver

7 Cara Menemukan Baris Duplikat di SQL Server sambil Mengabaikan Kunci Utama apa pun

Berikut adalah tujuh opsi untuk menemukan baris duplikat di SQL Server, ketika baris tersebut memiliki kunci utama atau kolom pengenal unik lainnya.

Dengan kata lain, tabel berisi dua atau lebih baris yang memiliki nilai yang sama persis di semua kolom kecuali untuk kolom pengenal uniknya.

Contoh Data

Misalkan kita memiliki tabel dengan data berikut:

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    |
+---------+-------------+------------+

Kita dapat melihat bahwa dua baris pertama adalah duplikat (kecuali untuk DogId kolom, yang berisi nilai unik di semua baris, dan dapat digunakan sebagai kolom kunci utama tabel). Kita juga dapat melihat bahwa tiga baris terakhir adalah duplikat (kecuali untuk DogId kolom).

Kolom ID unik memastikan bahwa tidak ada baris duplikat, yang biasanya merupakan sifat yang sangat diinginkan dalam RDBMS. Namun, dalam hal ini berpotensi mengganggu kemampuan kami untuk menemukan duplikat. Menurut definisi, kolom ID unik memastikan bahwa tidak ada duplikat. Untungnya, kami dapat mengatasi masalah ini dengan cukup mudah, seperti yang ditunjukkan oleh contoh berikut.

Opsi 1

Mungkin cara termudah/tersederhana untuk melakukannya adalah dengan kueri sederhana yang menggunakan GROUP BY klausa:

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

Hasil:

+-------------+------------+---------+
| FirstName   | LastName   | Count   |
|-------------+------------+---------|
| Wag         | Johnson    | 3       |
| Woof        | Jones      | 1       |
| Ruff        | Robinson   | 1       |
| Bark        | Smith      | 2       |
+-------------+------------+---------+

Kami dapat mengecualikan kunci utama/kolom ID unik 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).

Opsi 2

Kami dapat mengecualikan non-duplikat dari hasil dengan menyertakan HAVING klausa dalam kueri kami:

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

Kami juga dapat memeriksa duplikat pada kolom gabungan. Misalnya, kita dapat menggunakan CONCAT() fungsi untuk menggabungkan dua kolom kami:

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

Hasil:

+---------------+---------+
| DogName       | Count   |
|---------------+---------|
| Bark Smith    | 2       |
| Ruff Robinson | 1       |
| Wag Johnson   | 3       |
| Woof Jones    | 1       |
+---------------+---------+

Opsi 4

Kita dapat menggunakan ROW_NUMBER() fungsi dengan PARTITION BY klausa untuk membuat kolom baru dengan nomor baris yang bertambah setiap kali ada duplikat, tetapi disetel ulang lagi ketika ada baris unik:

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            |
+---------+-------------+------------+--------------+

Salah satu manfaat dari metode ini adalah kita dapat melihat setiap baris duplikat, beserta kolom pengenal uniknya, karena kita tidak mengelompokkan hasilnya.

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            |
+---------+-------------+------------+--------------+

Opsi ini mengecualikan non-duplikat dari output.

Itu juga mengecualikan tepat satu baris dari setiap duplikat dari output. Ini membuka pintu bagi kita untuk memutar SELECT * last terakhir menjadi DELETE untuk menghilangkan penipuan tabel sambil menyimpan satu dari setiap duplikat.

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 |
+-------+-----------+----------+
|     2 | Bark      | Smith    |
|     6 | Wag       | Johnson  |
|     7 | Wag       | Johnson  |
+-------+-----------+----------+

Contoh ini tidak memerlukan pembuatan nomor baris terpisah kita sendiri.

Opsi 7

Dan akhirnya, inilah teknik yang sedikit lebih rumit untuk mengembalikan baris duplikat:

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    |
+---------+-------------+------------+---------+-------------+------------+

Bahkan hasilnya terlihat lebih berbelit-belit, tapi hei, itu masih menunjukkan kepada kita duplikatnya!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kode VBA untuk Menambahkan Tabel Tertaut dengan Kunci Utama

  2. Cara menjatuhkan semua Kunci Utama dari semua tabel di Database SQL Server - Tutorial SQL Server / TSQL Bagian 65

  3. "Permintaan tidak diizinkan di Waitfor" Kesalahan 101 di SQL Server

  4. 3 Cara Mendapatkan Job Steps dari SQL Server Agent Job (T-SQL)

  5. Ganti Pengoptimal Kueri untuk Gabungan T-SQL Anda dengan FORCEPLAN