Saya punya tabel dengan bidang-bidang berikut:
id (Unique)
url (Unique)
title
company
site_id
Sekarang, saya perlu menghapus baris yang sama title, company and site_id
. Salah satu cara untuk melakukannya adalah menggunakan SQL berikut dengan skrip ( PHP
):
SELECT title, site_id, location, id, count( * )
FROM jobs
GROUP BY site_id, company, title, location
HAVING count( * ) >1
Setelah menjalankan kueri ini, saya bisa menghapus duplikat menggunakan skrip sisi server.
Tapi, saya ingin tahu apakah ini bisa dilakukan hanya menggunakan query SQL.
mysql
sql
duplicates
Chetan
sumber
sumber
Jawaban:
Cara yang sangat mudah untuk melakukan ini adalah dengan menambahkan
UNIQUE
indeks pada 3 kolom. Saat Anda menulisALTER
pernyataan, sertakanIGNORE
kata kunci. Seperti itu:Ini akan menghapus semua baris duplikat. Sebagai manfaat tambahan, masa depan
INSERTs
yang merupakan duplikat akan kesalahan. Seperti biasa, Anda mungkin ingin mengambil cadangan sebelum menjalankan sesuatu seperti ini ...sumber
set session old_alter_table=1;
Jika Anda tidak ingin mengubah properti kolom, maka Anda dapat menggunakan kueri di bawah ini.
Karena Anda memiliki kolom yang memiliki ID unik (misalnya,
auto_increment
kolom), Anda dapat menggunakannya untuk menghapus duplikat:Di MySQL, Anda dapat lebih menyederhanakannya dengan operator yang setara dengan NULL-safe (alias "operator pesawat ruang angkasa" ):
sumber
MySQL memiliki batasan tentang merujuk ke tabel yang Anda hapus. Anda bisa mengatasinya dengan tabel sementara, seperti:
Dari saran Kostanos di komentar:
Satu-satunya permintaan lambat di atas adalah DELETE, untuk kasus di mana Anda memiliki database yang sangat besar. Kueri ini bisa lebih cepat:
sumber
DELETE FROM YourTable USING YourTable, tmpTable WHERE YourTable.id=tmpTable.id
DELETE
, tetapi jugaINSERT
ke meja sementara, saya butuh waktu lama. Jadi indeks untuk tabel tmp bisa banyak membantucreate index tmpTable_id_index on tmpTable (id)
,, setidaknya untuk saya.create temporary table tmpTable (id int, PRIMARY KEY (id));
Jika
IGNORE
pernyataan itu tidak berfungsi seperti dalam kasus saya, Anda dapat menggunakan pernyataan di bawah ini:sumber
Menghapus duplikat pada tabel MySQL adalah masalah umum, itu secara umum merupakan hasil dari kendala yang hilang untuk menghindari duplikat tersebut sebelumnya. Tetapi masalah umum ini biasanya datang dengan kebutuhan spesifik ... yang memang membutuhkan pendekatan khusus. Pendekatan harus berbeda tergantung pada, misalnya, ukuran data, entri yang digandakan yang harus disimpan (umumnya yang pertama atau yang terakhir), apakah ada indeks yang akan disimpan, atau apakah kita ingin melakukan tambahan tindakan pada data yang digandakan.
Ada juga beberapa kekhususan pada MySQL itu sendiri, seperti tidak dapat mereferensikan tabel yang sama pada penyebab FROM saat melakukan UPDATE tabel (itu akan meningkatkan kesalahan MySQL # 1093). Batasan ini dapat diatasi dengan menggunakan kueri dalam dengan tabel sementara (seperti yang disarankan pada beberapa pendekatan di atas). Tetapi permintaan dalam ini tidak akan bekerja dengan baik ketika berhadapan dengan sumber data besar.
Namun, pendekatan yang lebih baik memang ada untuk menghapus duplikat, itu efisien dan dapat diandalkan, dan yang dapat dengan mudah disesuaikan dengan kebutuhan yang berbeda.
Gagasan umum adalah membuat tabel sementara baru, biasanya menambahkan batasan unik untuk menghindari duplikat lebih lanjut, dan untuk menyisipkan data dari tabel Anda sebelumnya ke yang baru, sambil menjaga duplikat. Pendekatan ini bergantung pada permintaan MySQL INSERT sederhana, menciptakan kendala baru untuk menghindari duplikat lebih lanjut, dan melompati kebutuhan menggunakan kueri batin untuk mencari duplikat dan tabel sementara yang harus disimpan dalam memori (sehingga menyesuaikan sumber data besar juga).
Ini adalah bagaimana hal itu dapat dicapai. Mengingat kami memiliki karyawan meja , dengan kolom berikut:
Untuk menghapus baris dengan kolom duplikat ssn , dan hanya menyimpan entri pertama yang ditemukan, proses berikut dapat diikuti:
Penjelasan teknis
⇒ Dengan menggunakan pendekatan ini, register 1,6M dikonversi menjadi 6k dalam waktu kurang dari 200an.
Chetan , mengikuti proses ini, Anda bisa dengan cepat dan mudah menghapus semua duplikat Anda dan membuat batasan UNIK dengan menjalankan:
Tentu saja, proses ini dapat dimodifikasi lebih lanjut untuk menyesuaikannya dengan kebutuhan yang berbeda saat menghapus duplikat. Beberapa contoh mengikuti.
✔ Variasi untuk menjaga entri terakhir, bukan yang pertama
Kadang-kadang kita perlu menyimpan entri yang digandakan terakhir daripada yang pertama.
✔ Variasi untuk melakukan beberapa tugas pada duplikat, misalnya menjaga hitungan pada duplikat yang ditemukan
Terkadang kita perlu melakukan beberapa pemrosesan lebih lanjut pada entri yang digandakan yang ditemukan (seperti menjaga jumlah duplikat).
✔ Variasi untuk meregenerasi id bidang penambahan-otomatis
Kadang-kadang kita menggunakan bidang penambahan otomatis dan, agar indeks tetap seringkas mungkin, kita bisa memanfaatkan penghapusan duplikat untuk membuat ulang bidang penambahan otomatis di tabel sementara yang baru.
✔ Variasi lebih lanjut
Banyak modifikasi lebih lanjut juga dapat dilakukan tergantung pada perilaku yang diinginkan. Sebagai contoh, kueri berikut akan menggunakan tabel sementara kedua, selain 1) menyimpan entri terakhir, bukan yang pertama; dan 2) menambah penghitung pada duplikat yang ditemukan; juga 3) meregenerasi id bidang penambahan otomatis sambil tetap menjaga urutan entri seperti pada data sebelumnya.
sumber
Ada solusi lain:
sumber
jika Anda memiliki tabel besar dengan jumlah record yang sangat besar maka solusi di atas tidak akan berfungsi atau membutuhkan terlalu banyak waktu. Maka kami memiliki solusi yang berbeda
sumber
Saya punya snipet query ini untuk SQLServer tapi saya pikir ini bisa digunakan di DBMS lain dengan sedikit perubahan:
Saya lupa memberi tahu Anda bahwa kueri ini tidak menghapus baris dengan id terendah dari baris yang diduplikasi. Jika ini berhasil, Anda dapat mencoba kueri ini:
sumber
ERROR 1093: You can't specify target table 'Table' for update in FROM clause
"You can't specify target table 'Table' for update in FROM..."
kesalahan, gunakan:DELETE FROM Table WHERE Table.idTable IN ( SELECT MAX(idTable) FROM (SELECT * FROM idTable) AS tmp GROUP BY field1, field2, field3 HAVING COUNT(*) > 1)
yang memaksa MySQL untuk membuat tabel sementara. Namun sangat lambat dalam kumpulan data besar ... dalam kasus seperti itu, saya akan merekomendasikan kode Andomar, yang jauh lebih cepat.Cara yang lebih cepat adalah memasukkan baris yang berbeda ke tabel sementara. Menggunakan delete, saya butuh beberapa jam untuk menghapus duplikat dari tabel 8 juta baris. Menggunakan insert dan berbeda, hanya butuh 13 menit.
sumber
TRUNCATE TABLE tableName
dan baris ke-5 harus mengatakanINSERT INTO tableName SELECT * FROM tempTableName;
Solusi yang mudah dipahami dan bekerja tanpa kunci utama:
1) tambahkan kolom boolean baru
2) menambahkan batasan pada kolom yang digandakan DAN kolom yang baru
3) setel kolom boolean ke true. Ini akan berhasil hanya pada salah satu baris yang digandakan karena kendala baru
4) hapus baris yang belum ditandai sebagai tokeep
5) jatuhkan kolom yang ditambahkan
Saya menyarankan Anda menjaga batasan yang Anda tambahkan, sehingga duplikat baru dicegah di masa mendatang.
sumber
Hapus baris duplikat menggunakan pernyataan DELETE JOIN MySQL memberi Anda pernyataan DELETE JOIN yang dapat Anda gunakan untuk menghapus baris duplikat dengan cepat.
Pernyataan berikut menghapus baris duplikat dan mempertahankan id tertinggi:
sumber
Saya menemukan cara sederhana. (tetap terbaru)
sumber
Sederhana dan cepat untuk semua kasus:
sumber
Ini akan menghapus baris duplikat dengan nilai yang sama untuk judul, perusahaan dan situs. Kejadian pertama akan disimpan dan sisanya semua duplikat akan dihapus
sumber
Saya terus mengunjungi halaman ini kapan saja saya google "menghapus duplikat formulir mysql" tetapi untuk solusi theIGNORE saya tidak berfungsi karena saya memiliki tabel mysql InnoDB
kode ini berfungsi lebih baik kapan saja
tableToclean = nama tabel yang perlu Anda bersihkan
tableToclean_temp = tabel sementara dibuat dan dihapus
sumber
Solusi ini akan memindahkan duplikat ke satu tabel dan yang unik ke yang lain .
sumber
SELECT * FROM jobs GROUP BY site_id, company, title, location
?Pada versi 8.0 (2018), MySQL akhirnya mendukung fungsi jendela .
Fungsi jendela berguna dan efisien. Berikut adalah solusi yang menunjukkan cara menggunakannya untuk menyelesaikan tugas ini.
Dalam subquery, kita bisa menggunakan
ROW_NUMBER()
untuk menetapkan posisi untuk setiap catatan dalam tabel dalamcolumn1/column2
kelompok, yang dipesan olehid
. Jika tidak ada duplikat, catatan akan mendapatkan nomor baris1
. Jika duplikat ada, mereka akan diberi nomor dengan naikid
(mulai dari1
).Setelah catatan diberi nomor dengan benar dalam subquery, permintaan luar hanya menghapus semua catatan yang nomor barisnya bukan 1.
Pertanyaan:
sumber
Untuk menghapus catatan duplikat dalam sebuah tabel.
atau
sumber
sumber
Agar dapat menggandakan rekaman dengan kolom unik, misalnya COL1, COL2, COL3 tidak boleh direplikasi (misalkan kita telah melewatkan 3 kolom yang unik dalam struktur tabel dan beberapa entri duplikat telah dibuat ke dalam tabel)
Semoga akan membantu dev.
sumber
TL; TR;
Tutorial yang sangat dijelaskan untuk mengatasi masalah ini dapat ditemukan di situs mysqltutorial.org :
Cara Menghapus Baris Duplikat di MySQL
Sangat jelas ditunjukkan cara menghapus duplikat baris dalam tiga cara berbeda :
A) Menggunakan
DELETE JOIN
pernyataanB) Menggunakan tabel perantara
C) Menggunakan
ROW_NUMBER()
fungsiSaya harap ini akan membantu seseorang.
sumber
Saya punya tabel yang lupa menambahkan kunci utama di baris id. Meskipun memiliki auto_increment pada id. Tetapi suatu hari, satu hal memutar ulang log mysql bin pada database yang menyisipkan beberapa baris duplikat.
Saya menghapus baris duplikat oleh
select T1.* from table_name T1 inner join (select count(*) as c,id from table_name group by id) T2 on T1.id = T2.id where T2.c > 1 group by T1.id;
hapus duplikat baris oleh id
masukkan baris dari data yang diekspor.
Kemudian tambahkan kunci utama pada id
sumber
Saya ingin sedikit lebih spesifik tentang catatan yang saya hapus jadi di sini adalah solusi saya:
sumber
Anda dapat dengan mudah menghapus rekaman duplikat dari kode ini ..
sumber
Saya harus melakukan ini dengan bidang teks dan menemukan batas 100 byte pada indeks.
Saya memecahkan ini dengan menambahkan kolom, melakukan hash md5 dari bidang, dan melakukan alter.
sumber