Cara paling sederhana adalah dengan CTE (common table expression). Saya menggunakan metode ini ketika saya memiliki data mentah untuk diimpor; hal pertama yang saya lakukan untuk membersihkannya adalah memastikan tidak ada duplikat---bahwa saya memiliki semacam pegangan unik untuk setiap baris.
Ringkasan:
WITH numbered AS (
SELECT ROW_NUMBER() OVER(PARTITION BY [dupe-column-list] ORDER BY [dupe-column-list]) AS _dupe_num FROM [table-name] WHERE 1=1
)
DELETE FROM numbered WHERE _dupe_num > 1;
Bagian "dupe-column-list" adalah tempat Anda mendaftar semua kolom yang terlibat di mana Anda ingin nilainya unik. ORDER BY adalah tempat Anda memutuskan, dalam satu set duplikat, baris mana yang "menang" dan mana yang dihapus. ("WHERE 1=1" hanyalah kebiasaan pribadi.)
Alasan kerjanya adalah karena Sql Server menyimpan referensi unik internal untuk setiap baris sumber yang dipilih di CTE. Jadi ketika DELETE dieksekusi, ia mengetahui baris yang tepat untuk dihapus, terlepas dari apa yang Anda masukkan ke dalam daftar pilih CTE Anda. (Jika Anda gugup, Anda dapat mengubah "HAPUS" menjadi "PILIH *", tetapi karena Anda memiliki baris duplikat, itu tidak akan membantu; jika Anda dapat mengidentifikasi setiap baris secara unik, Anda tidak akan membaca ini .)
Contoh:
CREATE TABLE ##_dupes (col1 int, col2 int, col3 varchar(50));
INSERT INTO ##_dupes
VALUES (1, 1, 'one,one')
, (2, 2, 'two,two')
, (3, 3, 'three,three')
, (1, 1, 'one,one')
, (1, 2, 'one,two')
, (3, 3, 'three,three')
, (1, 1, 'one,one')
, (1, 2, '1,2');
Dari 8 baris, Anda memiliki 5 yang terlibat dengan masalah duplikat; 3 baris harus dihapus. Anda dapat melihat masalah dengan ini:
SELECT col1
, col2
, col3
, COUNT(1) AS _total
FROM ##_dupes
WHERE 1=1
GROUP BY col1, col2, col3
HAVING COUNT(1) > 1
ORDER BY _total DESC;
Sekarang jalankan kueri berikut untuk menghapus duplikat, sisakan 1 baris dari setiap kumpulan duplikat.
WITH numbered AS (
SELECT ROW_NUMBER() OVER(PARTITION BY col1, col2, col3 ORDER BY col1, col2, col3) AS _dupe_num FROM ##_dupes WHERE 1=1
)
DELETE FROM numbered WHERE _dupe_num > 1;
Anda sekarang memiliki 5 baris, tidak ada yang diduplikasi.