Pertanyaan Bagaimana cara menghapus baris duplikat?


Apa cara terbaik untuk menghapus baris duplikat dari yang cukup besar SQL Server tabel (mis. 300.000 baris)?

Baris, tentu saja, tidak akan menjadi duplikat sempurna karena keberadaan RowID bidang identitas.

MyTable

RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null

1160
2017-08-20 21:51


asal


Jawaban:


Dengan asumsi tidak ada nol, Anda GROUP BY kolom unik, dan SELECT itu MIN (or MAX) RowId sebagai baris yang harus disimpan. Kemudian, hapus saja semua yang tidak memiliki baris id:

DELETE FROM MyTable
LEFT OUTER JOIN (
   SELECT MIN(RowId) as RowId, Col1, Col2, Col3 
   FROM MyTable 
   GROUP BY Col1, Col2, Col3
) as KeepRows ON
   MyTable.RowId = KeepRows.RowId
WHERE
   KeepRows.RowId IS NULL

Jika Anda memiliki GUID, bukan bilangan bulat, Anda dapat mengganti

MIN(RowId)

dengan

CONVERT(uniqueidentifier, MIN(CONVERT(char(36), MyGuidColumn)))

1062
2017-08-20 22:00



Cara lain yang mungkin untuk melakukan ini adalah

; 

--Ensure that any immediately preceding statement is terminated with a semicolon above
WITH cte
     AS (SELECT ROW_NUMBER() OVER (PARTITION BY Col1, Col2, Col3 
                                       ORDER BY ( SELECT 0)) RN
         FROM   #MyTable)
DELETE FROM cte
WHERE  RN > 1;

saya menggunakan ORDER BY (SELECT 0) di atas karena sewenang-wenang baris mana yang harus dipertahankan jika terjadi ikat.

Untuk melestarikan yang terbaru di RowID pesanan misalnya bisa Anda gunakan ORDER BY RowID DESC 

Rencana Eksekusi

Rencana pelaksanaan untuk ini seringkali lebih sederhana dan lebih efisien daripada jawaban yang diterima karena tidak mengharuskan diri bergabung.

Execution Plans

Namun ini tidak selalu terjadi. Satu tempat di mana GROUP BY solusi mungkin lebih disukai adalah situasi di mana suatu agregat hash akan dipilih dalam preferensi ke agregat aliran.

Itu ROW_NUMBER solusi akan selalu memberikan cukup banyak rencana yang sama sedangkan GROUP BY strategi lebih fleksibel.

Execution Plans

Faktor-faktor yang mungkin mendukung pendekatan agregat hash akan

  • Tidak ada indeks yang berguna pada kolom partisi
  • kelompok yang relatif lebih sedikit dengan duplikat yang relatif lebih banyak di masing-masing kelompok

Dalam versi ekstrim dari kasus kedua ini (jika ada sangat sedikit grup dengan banyak duplikat di masing-masing), seseorang juga dapat mempertimbangkan hanya memasukkan baris-baris untuk disimpan ke dalam tabel baru kemudian TRUNCATE-menggunakan yang asli dan menyalinnya kembali untuk meminimalkan penebangan dibandingkan dengan menghapus sebagian besar baris.


700
2017-09-29 14:52



Ada artikel bagus tentangnya menghapus duplikat di situs Dukungan Microsoft. Ini cukup konservatif - mereka meminta Anda melakukan semuanya dalam langkah-langkah terpisah - tetapi itu harus bekerja dengan baik terhadap tabel besar.

Saya telah menggunakan self-join untuk melakukan hal ini di masa lalu, meskipun mungkin bisa dipreparasi dengan klausa HAVING:

DELETE dupes
FROM MyTable dupes, MyTable fullTable
WHERE dupes.dupField = fullTable.dupField 
AND dupes.secondDupField = fullTable.secondDupField 
AND dupes.uniqueField > fullTable.uniqueField

132
2017-08-20 21:53



Query berikut berguna untuk menghapus duplikasi baris. Tabel dalam contoh ini ID sebagai kolom identitas dan kolom yang memiliki data duplikat Column1, Column2 dan Column3.

DELETE FROM TableName
WHERE  ID NOT IN (SELECT MAX(ID)
                  FROM   TableName
                  GROUP  BY Column1,
                            Column2,
                            Column3
                  /*Even if ID is not null-able SQL Server treats MAX(ID) as potentially
                    nullable. Because of semantics of NOT IN (NULL) including the clause
                    below can simplify the plan*/
                  HAVING MAX(ID) IS NOT NULL) 

Naskah berikut menunjukkan penggunaan GROUP BY, HAVING, ORDER BY dalam satu permintaan, dan mengembalikan hasil dengan duplikat kolom dan hitungannya.

SELECT YourColumnName,
       COUNT(*) TotalCount
FROM   YourTableName
GROUP  BY YourColumnName
HAVING COUNT(*) > 1
ORDER  BY COUNT(*) DESC 

87
2017-11-23 15:32



delete t1
from table t1, table t2
where t1.columnA = t2.columnA
and t1.rowid>t2.rowid

Postingan:

delete
from table t1
using table t2
where t1.columnA = t2.columnA
and t1.rowid > t2.rowid

52
2017-09-30 02:35



DELETE LU 
FROM   (SELECT *, 
               Row_number() 
                 OVER ( 
                   partition BY col1, col1, col3 
                   ORDER BY rowid DESC) [Row] 
        FROM   mytable) LU 
WHERE  [row] > 1 

41
2018-05-21 07:54



Ini akan menghapus duplikasi baris, kecuali baris pertama

DELETE
FROM
    Mytable
WHERE
    RowID NOT IN (
        SELECT
            MIN(RowID)
        FROM
            Mytable
        GROUP BY
            Col1,
            Col2,
            Col3
    )

Lihat (http://www.codeproject.com/Articles/157977/Remove-Duplicate-Rows-from-a-Table-in-SQL-Server)


36
2017-09-10 13:07



Saya lebih suka CTE untuk menghapus baris duplikat dari tabel sql server

sangat menyarankan untuk mengikuti artikel ini ::http://dotnetmob.com/sql-server-article/delete-duplicate-rows-in-sql-server/

dengan menyimpan yang asli

WITH CTE AS
(
SELECT *,ROW_NUMBER() OVER (PARTITION BY col1,col2,col3 ORDER BY col1,col2,col3) AS RN
FROM MyTable
)

DELETE FROM CTE WHERE RN<>1

tanpa menyimpan yang asli

WITH CTE AS
(SELECT *,R=RANK() OVER (ORDER BY col1,col2,col3)
FROM MyTable)
 
DELETE CTE
WHERE R IN (SELECT R FROM CTE GROUP BY R HAVING COUNT(*)>1)

22
2018-05-19 14:35