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

3 Cara Menghapus Baris Duplikat di SQL Server sambil Mengabaikan Kunci Utama

Contoh berikut menggunakan T-SQL untuk menghapus baris duplikat di SQL Server sambil mengabaikan kunci utama atau kolom pengenal unik.

Lebih khusus lagi, contoh menghapus baris duplikat tetapi menyimpannya. Jadi, mengingat dua baris identik, satu dihapus dan yang lainnya tetap. Ini sering disebut sebagai "de-duping" tabel, "deduplikasi" tabel, dll.

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, begitu pula tiga baris terakhir.

Opsi 1

Pertama, jalankan kode berikut untuk memeriksa baris mana yang akan di-de-duped:

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

Kami menggunakan ROW_NUMBER() fungsi dengan PARTITION BY klausa untuk membuat nomor baris kita sendiri yang bertambah ketika ada duplikat ditemukan, dan diatur ulang ketika non-duplikat ditemukan. Angka yang lebih besar dari 1 menunjukkan bahwa itu duplikat, jadi kami hanya menampilkan baris yang memiliki angka lebih besar dari 1.

Kita dapat melihat bahwa tiga baris akan dihapus saat kita menghapus penipuan pada tabel ini.

Sekarang mari kita de-dupe tabel:

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

Hasil:

(3 rows affected)

Seperti yang diharapkan, tiga baris telah dihapus.

Permintaan ini hampir identik dengan yang sebelumnya. Yang kami lakukan hanyalah mengubah SELECT * pada baris terakhir ke DELETE .

Sekarang mari kita pilih semua baris dari tabel untuk memverifikasi bahwa baris yang benar telah dihapus:

SELECT * FROM Dogs;

Hasil:

+---------+-------------+------------+
| DogId   | FirstName   | LastName   |
|---------+-------------+------------|
| 1       | Bark        | Smith      |
| 3       | Woof        | Jones      |
| 4       | Ruff        | Robinson   |
| 5       | Wag         | Johnson    |
+---------+-------------+------------+

Kita dapat melihat bahwa setiap anjing sekarang hanya muncul sekali di tabel.

Opsi 2

Dengan asumsi bahwa tabel telah dipulihkan setelah contoh sebelumnya, berikut cara lain untuk memeriksa duplikat:

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

Dalam hal ini, kami menggunakan EXCEPT operator bersama dengan MIN() fungsi. Kita bisa mengganti MIN() dengan MAX() tergantung pada baris mana yang ingin kita hapus.

Untuk menghapus baris, kita cukup mengganti SELECT * dengan DELETE :

DELETE FROM Dogs 
WHERE DogId IN (
    SELECT DogId FROM Dogs 
    EXCEPT SELECT MIN(DogId) FROM Dogs 
    GROUP BY FirstName, LastName
    );

Hasil:

(3 rows affected)

Dan periksa untuk melihat apa yang tersisa:

SELECT * FROM Dogs;

Hasil:

+---------+-------------+------------+
| DogId   | FirstName   | LastName   |
|---------+-------------+------------|
| 1       | Bark        | Smith      |
| 3       | Woof        | Jones      |
| 4       | Ruff        | Robinson   |
| 5       | Wag         | Johnson    |
+---------+-------------+------------+

Opsi 3

Cara lain untuk melakukannya adalah dengan menggabungkan tabel itu sendiri dan memeriksa duplikat dengan cara itu.

Dengan asumsi bahwa tabel telah dipulihkan setelah contoh sebelumnya, inilah opsi ketiga kami untuk memilih 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    |
+---------+-------------+------------+---------+-------------+------------+

Hasil ini tidak sejelas pada contoh sebelumnya, tetapi kita masih dapat melihat baris mana yang merupakan duplikat.

Sekarang kita dapat memodifikasi kueri itu sehingga kita menghapus baris duplikat:

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
    )
);

Hasil:

(3 rows affected)

Sekali lagi, tiga baris dihapus.

Mari kita periksa lagi tabelnya:

SELECT * FROM Dogs;

Hasil:

+---------+-------------+------------+
| DogId   | FirstName   | LastName   |
|---------+-------------+------------|
| 2       | Bark        | Smith      |
| 3       | Woof        | Jones      |
| 4       | Ruff        | Robinson   |
| 7       | Wag         | Johnson    |
+---------+-------------+------------+

Anda mungkin memperhatikan bahwa kali ini baris lain telah dihapus. Dengan kata lain, kita sekarang memiliki DogId s 2, 3, 4, dan 7 sedangkan pada contoh sebelumnya kita dibiarkan dengan 1, 3, 4, dan 5.

Kita dapat dengan mudah mengubah contoh ini untuk menghapus baris yang sama seperti contoh sebelumnya. Untuk melakukan ini, kita dapat menggunakan MIN() fungsi alih-alih MAX() fungsi:

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 MIN(DogId) 
        FROM Dogs d3 
        WHERE d3.FirstName = d1.FirstName 
        AND d3.LastName = d1.LastName
    )
);

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL 'LIKE' query menggunakan '%' di mana kriteria pencarian berisi '%'

  2. Cara Membulatkan (ATAS/BAWAH) di SQL Server – 5 Tips Berguna

  3. SQL Server:Contoh data PIVOTing String

  4. T-SQL untuk menemukan Nama Server Jarak Jauh dari server yang ditautkan

  5. Bekerja dengan Data Salesforce.com di Layanan Pelaporan SQL Server