Menghapus baris duplikat di MySQL di tempat, (Asumsikan Anda memiliki timestamp col untuk diurutkan berdasarkan) panduan:
Buat tabel dan masukkan beberapa baris:
create table penguins(foo int, bar varchar(15), baz datetime);
insert into penguins values(1, 'skipper', now());
insert into penguins values(1, 'skipper', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(3, 'kowalski', now());
insert into penguins values(4, 'rico', now());
select * from penguins;
+------+----------+---------------------+
| foo | bar | baz |
+------+----------+---------------------+
| 1 | skipper | 2014-08-25 14:21:54 |
| 1 | skipper | 2014-08-25 14:21:59 |
| 3 | kowalski | 2014-08-25 14:22:09 |
| 3 | kowalski | 2014-08-25 14:22:13 |
| 3 | kowalski | 2014-08-25 14:22:15 |
| 4 | rico | 2014-08-25 14:22:22 |
+------+----------+---------------------+
6 rows in set (0.00 sec)
Hapus duplikat di tempat:
delete a
from penguins a
left join(
select max(baz) maxtimestamp, foo, bar
from penguins
group by foo, bar) b
on a.baz = maxtimestamp and
a.foo = b.foo and
a.bar = b.bar
where b.maxtimestamp IS NULL;
Query OK, 3 rows affected (0.01 sec)
select * from penguins;
+------+----------+---------------------+
| foo | bar | baz |
+------+----------+---------------------+
| 1 | skipper | 2014-08-25 14:21:59 |
| 3 | kowalski | 2014-08-25 14:22:15 |
| 4 | rico | 2014-08-25 14:22:22 |
+------+----------+---------------------+
3 rows in set (0.00 sec)
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
create table penguins(foo int, bar varchar(15));
insert into penguins values(1, 'skipper');
insert into penguins values(1, 'skipper');
insert into penguins values(3, 'kowalski');
insert into penguins values(3, 'kowalski');
insert into penguins values(3, 'kowalski');
insert into penguins values(4, 'rico');
select * from penguins;
# +------+----------+
# | foo | bar |
# +------+----------+
# | 1 | skipper |
# | 1 | skipper |
# | 3 | kowalski |
# | 3 | kowalski |
# | 3 | kowalski |
# | 4 | rico |
# +------+----------+
buat klon dari tabel pertama dan salin ke dalamnya.
drop table if exists penguins_copy;
create table penguins_copy as ( SELECT foo, bar FROM penguins );
#add an autoincrementing primary key:
ALTER TABLE penguins_copy ADD moo int AUTO_INCREMENT PRIMARY KEY first;
select * from penguins_copy;
# +-----+------+----------+
# | moo | foo | bar |
# +-----+------+----------+
# | 1 | 1 | skipper |
# | 2 | 1 | skipper |
# | 3 | 3 | kowalski |
# | 4 | 3 | kowalski |
# | 5 | 3 | kowalski |
# | 6 | 4 | rico |
# +-----+------+----------+
Agregat maks beroperasi pada indeks moo baru:
delete a from penguins_copy a left join(
select max(moo) myindex, foo, bar
from penguins_copy
group by foo, bar) b
on a.moo = b.myindex and
a.foo = b.foo and
a.bar = b.bar
where b.myindex IS NULL;
#drop the extra column on the copied table
alter table penguins_copy drop moo;
select * from penguins_copy;
#drop the first table and put the copy table back:
drop table penguins;
create table penguins select * from penguins_copy;
amati dan bersihkan
drop table penguins_copy;
select * from penguins;
+------+----------+
| foo | bar |
+------+----------+
| 1 | skipper |
| 3 | kowalski |
| 4 | rico |
+------+----------+
Elapsed: 1458.359 milliseconds
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.