Saya perlu DELETE
menduplikasi baris untuk sid yang ditentukan di atas MySQL
meja.
Bagaimana saya bisa melakukan ini dengan query SQL?
DELETE (DUPLICATED TITLES) FROM table WHERE SID = "1"
Sesuatu seperti ini, tetapi saya tidak tahu bagaimana melakukannya.
mysql
duplicates
Ali Demirci
sumber
sumber
Jawaban:
ini menghapus duplikat di tempatnya, tanpa membuat tabel baru
Catatan: hanya berfungsi dengan baik jika indeks sesuai dalam memori
sumber
ALTER IGNORE
.ALTER TABLE foo ENGINE MyISAM
untuk mengatasinya, mengganti mesin kembali setelah.Misalkan Anda memiliki tabel
employee
, dengan kolom berikut:Untuk menghapus baris dengan
first_name
kolom duplikat :sumber
employee
melawan dirinya sendiri untuk satu pertandingan indeks dan satu>
pemeriksaan indeks akan lambat untuk tabel besar. Bukankah lebih baikSELECT MAX(ID) FROM t GROUP BY unique
dan kemudianJOIN
dengan kecocokan persisID
keMAX(ID)
?Mengikuti menghapus duplikat untuk semua SID-s, tidak hanya satu.
Dengan meja temp
Sejak
temp_table
baru dibuat tidak memiliki indeks. Anda harus membuatnya ulang setelah menghapus duplikat. Anda dapat memeriksa indeks apa yang Anda miliki di tabelSHOW INDEXES IN table
Tanpa tabel temp:
sumber
SELECT * FROM table GROUP BY title, SID;
Itu semua tergantung pada seberapa baik Anda tahu apa yang Anda lakukan.Menghapus baris duplikat di MySQL di tempat, (Asumsikan Anda memiliki timestamp col untuk diurutkan berdasarkan) panduan:
Buat tabel dan masukkan beberapa baris:
Hapus duplikat di tempat:
Anda selesai, baris duplikat dihapus, yang terakhir dengan stempel waktu disimpan.
Bagi Anda tanpa stempel waktu atau kolom unik.
Anda tidak punya
timestamp
kolom indeks unik atau untuk disortir? Anda hidup dalam kondisi degenerasi. Anda harus melakukan langkah-langkah tambahan untuk menghapus baris duplikat.buat tabel penguin dan tambahkan beberapa baris
buat klon dari tabel pertama dan salin ke dalamnya.
Agregat maks beroperasi pada indeks moo baru:
amati dan bersihkan
Apa yang dilakukan pernyataan penghapusan SQL besar itu?
Penguin tabel dengan alias 'a' dibiarkan bergabung pada subset penguin tabel yang disebut alias 'b'. Tabel kanan 'b' yang merupakan himpunan bagian menemukan timestamp max [atau maks moo] dikelompokkan berdasarkan kolom foo dan bar. Ini cocok dengan tabel sebelah kiri 'a'. (foo, bar, baz) di sebelah kiri memiliki setiap baris di tabel. Subset kanan 'b' memiliki (maxtimestamp, foo, bar) yang dicocokkan dengan kiri hanya pada yang memiliki maks.
Setiap baris yang bukan berarti max memiliki nilai maxtimestamp dari NULL. Saring ke bawah pada baris NULL tersebut dan Anda memiliki satu set semua baris yang dikelompokkan berdasarkan foo dan bar yang bukan cap timestamp terbaru. Hapus yang itu.
Buat cadangan tabel sebelum Anda menjalankan ini.
Cegah agar masalah ini tidak terjadi lagi di tabel ini:
Jika Anda berhasil, dan ini memadamkan "duplikat baris" Anda. Bagus. Sekarang tentukan kunci unik komposit baru pada tabel Anda (pada dua kolom itu) untuk mencegah duplikat ditambahkan dari awal.
Seperti sistem kekebalan yang baik, baris-baris yang buruk seharusnya tidak diperbolehkan masuk ke meja pada saat dimasukkan. Nanti semua program yang menambahkan duplikat akan menyiarkan protes mereka, dan ketika Anda memperbaikinya, masalah ini tidak pernah muncul lagi.
sumber
ID
kolom kenaikan otomatis makaON
klausa hanya perlu cocok denganID
kolom, tidak ada yang lain.Setelah mengalami sendiri masalah ini, pada basis data yang sangat besar, saya tidak sepenuhnya terkesan dengan kinerja dari jawaban yang lain. Saya hanya ingin menyimpan baris duplikat terbaru, dan menghapus sisanya.
Dalam pernyataan satu-permintaan, tanpa tabel temp, ini bekerja paling baik untuk saya,
Satu-satunya peringatan adalah bahwa saya harus menjalankan kueri beberapa kali, tetapi bahkan dengan itu, saya menemukan itu bekerja lebih baik untuk saya daripada opsi lainnya.
sumber
Ini sepertinya selalu berhasil bagi saya:
Yang menyimpan ID terendah pada masing-masing dupes dan sisa catatan non-dupe.
Saya juga harus melakukan yang berikut sehingga masalah dupe tidak lagi terjadi setelah penghapusan:
Dengan kata lain, saya membuat duplikat dari tabel pertama, menambahkan indeks unik pada bidang yang saya tidak ingin duplikat, dan kemudian melakukan
Insert IGNORE
yang memiliki keuntungan tidak gagal seperti biasaInsert
akan pertama kali mencoba menambahkan catatan duplikat berdasarkan dua bidang dan lebih baik mengabaikan catatan tersebut.Memindahkan fwd menjadi tidak mungkin untuk membuat rekaman duplikat berdasarkan kedua bidang tersebut.
sumber
ORDER BY
jawabanSELECT
untuk memastikan rekaman mana yang benar-benar membuatnyaNoDupeTable
?ORDER by ID Asc
tidak ada salahnya, jadi saya akan mengedit jawaban saya tanpa masalah.Select Max(ID)
dan kemudianOrder by Max(ID)
tetapi semua yang akan dilakukan adalah membalik urutan insert. Untuk mengambil ID tertinggi akan dibutuhkan, saya yakin pilih join yang lebih kompleks, terlepas dari bagaimana Anda memesan di atas, Anda akan mengambil nilai field dari ID yang lebih rendah.MAX(ID)
atauMIN(ID)
dan nama kolom daripada*
diSELECT FROM DupeTable
olah, kalau tidak, Anda hanya akan mendapatkan salah satu dariID
itu secara acak. Faktanya, banyak SQL dan bahkan MySQL yang ketat mengharuskan pemanggilan fungsi agregat pada setiap kolom yang tidak ditentukan dalamGROUP BY
klausa.ID,First,Last,Notes
dan catatan1,Bob,Smith,NULL
dan2,Bob,Smith,Arrears
kemudian melakukanSELECT *Max(ID), First,Last,Notes FROM DupeTable group by First,Last
keduanya akan mengembalikan catatan yang sama, 1, kecuali dengan ID yang berbeda. Max (ID) akan kembali2,Bob,Smith,NULL
dan Min (ID) akan kembali1,Bob,Smith,NULL
. Untuk mendapatkan catatan kedua dengan `Tunggakan 'di catatan, saya harus bergabung.Berikut ini berfungsi untuk semua tabel
sumber
Ini jawaban sederhana:
sumber
and a.id_field = b.id
LEFT JOIN
untukb
hanya perlu untuk membandingkanb.id
=a.id_field
asumsifield_id
adalah ID kenaikan otomatis unik. begitua.field_being_repeated = b.field_being_repeated
juga asing. (jugab.id_field
tidak ada dalam permintaan inib.id
.Ini berfungsi bagi saya untuk menghapus catatan lama:
Anda dapat mengganti min (e.id) ke maks (e.id) untuk menghapus catatan terbaru.
sumber
sumber
Saya menemukan solusi Werner di atas menjadi yang paling nyaman karena berfungsi terlepas dari keberadaan kunci utama, tidak mengacaukan tabel, menggunakan sql polos yang tahan masa depan, sangat mudah dimengerti.
Seperti yang saya nyatakan dalam komentar saya, solusi itu belum dijelaskan dengan baik. Jadi ini milikku, berdasarkan itu.
1) tambahkan kolom boolean baru
2) menambahkan batasan pada kolom yang digandakan DAN kolom yang baru
3) setel kolom boolean menjadi 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
Prosedur ini akan menghapus semua duplikat (termasuk kelipatan) dalam sebuah tabel, menjaga duplikat terakhir. Ini adalah perpanjangan dari Mengambil catatan terakhir di setiap grup
Semoga ini bermanfaat bagi seseorang.
sumber
Cara mudah lainnya ... menggunakan UPDATE IGNORE:
Anda harus menggunakan indeks pada satu atau beberapa kolom (ketik indeks). Buat kolom referensi sementara baru (bukan bagian dari indeks). Di kolom ini, Anda menandai unik dengan memperbarui dengan mengabaikan klausa. Selangkah demi selangkah:
Tambahkan kolom referensi sementara untuk menandai uniques:
=> ini akan menambahkan kolom ke tabel Anda.
Perbarui tabel, coba tandai semuanya sebagai unik, tetapi abaikan kemungkinan kesalahan karena masalah duplikat kunci (catatan akan dilewati):
=> Anda akan menemukan catatan duplikat Anda tidak akan ditandai sebagai unik = 'Ya', dengan kata lain hanya satu dari setiap set rekaman duplikat akan ditandai sebagai unik.
Hapus semua yang tidak unik:
=> Ini akan menghapus semua catatan duplikat.
Jatuhkan kolom ...
sumber
unique
kolom HARUS ditambahkan ke batasan unik bersama dengan kolom yang saat ini diduplikasi, jika tidak semuanya bekerja karena SETunique
= 'Ya' tidak akan pernah gagal.unique
adalah kata kunci mysql. Jadi itu harus memiliki backticks (seperti yang sudah ditampilkan dengan benar). Menggunakan kata lain untuk kolom mungkin lebih nyaman.Menghapus duplikat pada tabel MySQL adalah masalah umum, yang biasanya disertai dengan kebutuhan spesifik. Jika ada yang tertarik, di sini ( Hapus baris duplikat di MySQL ) Saya menjelaskan cara menggunakan tabel sementara untuk menghapus duplikat MySQL dengan cara yang andal dan cepat, juga berlaku untuk menangani sumber data besar (dengan contoh untuk berbagai kasus penggunaan).
Ali , dalam kasus Anda, Anda dapat menjalankan sesuatu seperti ini:
sumber
sumber
Love @ eric menjawab tetapi tampaknya tidak berhasil jika Anda memiliki meja yang sangat besar (saya mengerti
The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay
ketika saya mencoba menjalankannya). Jadi saya membatasi permintaan bergabung hanya mempertimbangkan baris duplikat dan saya berakhir dengan:Klausa WHERE dalam hal ini memungkinkan MySQL untuk mengabaikan setiap baris yang tidak memiliki duplikat dan juga akan mengabaikan jika ini adalah contoh pertama dari duplikat sehingga hanya duplikat berikutnya yang akan diabaikan. Ubah
MIN(baz)
untukMAX(baz)
mempertahankan instance terakhir, bukan yang pertama.sumber
Ini berfungsi untuk tabel besar:
Untuk menghapus perubahan terlama
max(id)
menjadimin(id)
sumber
Ini di sini akan membuat kolom
column_name
menjadi kunci utama, dan sementara itu mengabaikan semua kesalahan. Jadi itu akan menghapus baris dengan nilai duplikat untukcolumn_name
.sumber
Saya pikir ini akan bekerja dengan pada dasarnya menyalin tabel dan mengosongkannya kemudian hanya mengembalikan nilai yang berbeda ke dalamnya, tetapi harap periksa kembali sebelum melakukannya pada sejumlah besar data.
Membuat salinan karbon dari meja Anda
Kosongkan tabel asli Anda
Menyalin semua nilai yang berbeda dari tabel yang disalin kembali ke tabel asli Anda
Hapus tabel temp Anda.
Anda perlu mengelompokkan berdasarkan bidang aLL yang Anda ingin tetap berbeda.
sumber
sumber
di sini adalah bagaimana saya biasanya menghilangkan duplikat
sumber
Anda hanya bisa menggunakan klausul yang berbeda untuk memilih "dibersihkan" daftar (dan di sini adalah contoh yang sangat mudah tentang cara untuk melakukan itu).
sumber
DISTINCT
Anda kehilangan semua informasi tentang duplikat yang mungkin Anda miliki di tempat pertama. Bisakah Anda menunjukkan cara untuk menghapus duplikat menggunakannya?Bisakah ini berfungsi jika Anda menghitungnya, dan kemudian menambahkan batas ke permintaan penghapusan Anda hanya menyisakan satu?
Misalnya, jika Anda memiliki dua atau lebih, tulis kueri Anda seperti ini:
sumber
Hanya ada beberapa langkah dasar saat menghapus data duplikat dari tabel Anda:
Ini tutorial lengkapnya: https://blog.teamsql.io/deleting-duplicate-data-3541485b3473
sumber