Berikut adalah empat metode yang dapat Anda gunakan untuk menemukan baris duplikat di SQL Server.
Yang saya maksud dengan "baris duplikat" adalah dua atau lebih baris yang memiliki nilai yang sama persis di semua kolom.
Contoh Data
Misalkan kita memiliki tabel dengan data berikut:
SELECT * FROM Pets;
Hasil:
+---------+-----------+-----------+ | PetId | PetName | PetType | |---------+-----------+-----------| | 1 | Wag | Dog | | 1 | Wag | Dog | | 2 | Scratch | Cat | | 3 | Tweet | Bird | | 4 | Bark | Dog | | 4 | Bark | Dog | | 4 | Bark | Dog | +---------+-----------+-----------+
Kita dapat melihat bahwa dua baris pertama adalah duplikat, seperti halnya tiga baris terakhir.
Opsi 1
Kami dapat menggunakan kueri berikut untuk mengembalikan informasi tentang baris duplikat:
SELECT
DISTINCT PetId,
COUNT(*) AS "Count"
FROM Pets
GROUP BY PetId
ORDER BY PetId;
Hasil:
+---------+---------+ | PetId | Count | |---------+---------| | 1 | 2 | | 2 | 1 | | 3 | 1 | | 4 | 3 | +---------+---------+
Kita dapat memperluas SELECT
daftar untuk memasukkan lebih banyak kolom jika diperlukan:
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
ORDER BY PetId;
Hasil:
+---------+-----------+-----------+---------+ | PetId | PetName | PetType | Count | |---------+-----------+-----------+---------| | 1 | Wag | Dog | 2 | | 2 | Scratch | Cat | 1 | | 3 | Tweet | Bird | 1 | | 4 | Bark | Dog | 3 | +---------+-----------+-----------+---------+
Jika tabel memiliki pengidentifikasi unik, kita cukup menghapus kolom itu dari kueri. Misalnya, jika kita berasumsi bahwa PetId
kolom sebenarnya adalah kolom kunci utama yang berisi ID unik, kita dapat menjalankan kueri berikut untuk mengembalikan semua baris yang merupakan duplikat, tidak termasuk kolom kunci utama:
SELECT
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetName,
PetType
ORDER BY PetName;
Hasil:
+-----------+-----------+---------+ | PetName | PetType | Count | |-----------+-----------+---------| | Bark | Dog | 3 | | Scratch | Cat | 1 | | Tweet | Bird | 1 | | Wag | Dog | 2 | +-----------+-----------+---------+
Opsi 2
Jika kita hanya ingin baris duplikat yang sebenarnya dikembalikan, kita dapat menambahkan HAVING
klausa:
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
HAVING COUNT(*) > 1
ORDER BY PetId;
Hasil:
+---------+-----------+-----------+---------+ | PetId | PetName | PetType | Count | |---------+-----------+-----------+---------| | 1 | Wag | Dog | 2 | | 4 | Bark | Dog | 3 | +---------+-----------+-----------+---------+
Opsi 3
Cara lain untuk melakukannya adalah dengan menggunakan ROW_NUMBER()
fungsi dengan PARTITION BY
klausa untuk memberi nomor pada output dari kumpulan hasil.
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY PetId, PetName, PetType
ORDER BY PetId, PetName, PetType
) AS Row_Number
FROM Pets;
Hasil:
+---------+-----------+-----------+--------------+ | PetId | PetName | PetType | Row_Number | |---------+-----------+-----------+--------------| | 1 | Wag | Dog | 1 | | 1 | Wag | Dog | 2 | | 2 | Scratch | Cat | 1 | | 3 | Tweet | Bird | 1 | | 4 | Bark | Dog | 1 | | 4 | Bark | Dog | 2 | | 4 | Bark | Dog | 3 | +---------+-----------+-----------+--------------+
PARTITION BY
klausa membagi set hasil yang dihasilkan oleh FROM
klausa ke dalam partisi tempat fungsi diterapkan. Saat kita menentukan partisi untuk kumpulan hasil, setiap partisi menyebabkan penomoran dimulai dari awal lagi (yaitu penomoran akan dimulai dari 1 untuk baris pertama di setiap partisi).
Opsi 4
Jika kita hanya ingin kelebihan baris dari duplikat yang cocok dikembalikan, kita dapat menggunakan kueri di atas sebagai ekspresi tabel yang umum, seperti ini:
WITH CTE AS
(
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY PetId, PetName, PetType
ORDER BY PetId, PetName, PetType
) AS Row_Number
FROM Pets
)
SELECT * FROM CTE WHERE Row_Number <> 1;
Hasil:
+---------+-----------+-----------+--------------+ | PetId | PetName | PetType | Row_Number | |---------+-----------+-----------+--------------| | 1 | Wag | Dog | 2 | | 4 | Bark | Dog | 2 | | 4 | Bark | Dog | 3 | +---------+-----------+-----------+--------------+
Salah satu keuntungan melakukan ini adalah kita dapat menghapus baris duplikat hanya dengan mengganti SELECT *
untuk DELETE
(di baris terakhir).
Oleh karena itu kita dapat menggunakan kode di atas untuk melihat baris mana yang akan dihapus, dan kemudian ketika kita yakin bahwa kita akan menghapus baris yang benar, kita dapat mengubahnya menjadi DELETE
pernyataan untuk benar-benar menghapusnya.
Seperti ini:
WITH CTE AS
(
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY PetId, PetName, PetType
ORDER BY PetId, PetName, PetType
) AS Row_Number
FROM Pets
)
DELETE FROM CTE WHERE Row_Number <> 1;