Xóa các hàng trùng lặp trong MySQL tại chỗ, (Giả sử bạn có dấu thời gian col để sắp xếp theo) walk walk:
Tạo bảng và chèn một số hàng:
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)
Loại bỏ các bản sao tại chỗ:
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)
Bạn đã hoàn tất, các hàng trùng lặp được xóa, lần cuối cùng bằng dấu thời gian được giữ lại.
Đối với những người không có dấu thời gian hoặc cột duy nhất.
Bạn không có timestamp
hoặc một cột chỉ mục duy nhất để sắp xếp theo? Bạn đang sống trong tình trạng thoái hóa. Bạn sẽ phải làm các bước bổ sung để xóa các hàng trùng lặp.
tạo bảng chim cánh cụt và thêm một số hàng
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 |
# +------+----------+
tạo một bản sao của bảng đầu tiên và sao chép vào nó.
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 |
# +-----+------+----------+
Tổng hợp tối đa hoạt động theo chỉ số moo mới:
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;
quan sát và dọn dẹp
drop table penguins_copy;
select * from penguins;
+------+----------+
| foo | bar |
+------+----------+
| 1 | skipper |
| 3 | kowalski |
| 4 | rico |
+------+----------+
Elapsed: 1458.359 milliseconds
Câu lệnh xóa SQL lớn đó đang làm gì?
Chim cánh cụt bảng có bí danh 'a' được nối lại trên một tập hợp con chim cánh cụt bảng được gọi là bí danh 'b'. Bảng bên phải 'b' là tập hợp con tìm dấu thời gian tối đa [hoặc max moo] được nhóm theo cột foo và bar. Điều này được khớp với bảng bên trái 'a'. (foo, bar, baz) bên trái có mỗi hàng trong bảng. Tập hợp con bên phải 'b' có một (maxtimestamp, foo, bar) được khớp với bên trái chỉ trên một cái là tối đa.
Mỗi hàng không phải là max có giá trị maxtimestamp của NULL. Lọc xuống các hàng NULL đó và bạn có một tập hợp tất cả các hàng được nhóm theo foo và thanh không phải là dấu thời gian mới nhất. Xóa những cái đó đi.
Tạo một bản sao lưu của bảng trước khi bạn chạy này.
Ngăn chặn vấn đề này không bao giờ xảy ra nữa trên bảng này:
Nếu bạn làm điều này để làm việc, và nó sẽ dập tắt "hàng trùng lặp" của bạn. Tuyệt quá. Bây giờ hãy xác định một khóa duy nhất tổng hợp mới trên bảng của bạn (trên hai cột đó) để ngăn không cho thêm các mục trùng lặp ở vị trí đầu tiên.
Giống như một hệ thống miễn dịch tốt, các hàng xấu thậm chí không được phép vào bảng tại thời điểm chèn. Sau đó, tất cả các chương trình thêm các bản sao sẽ phát đi sự phản đối của họ và khi bạn sửa chúng, vấn đề này sẽ không bao giờ xuất hiện nữa.