Loại bỏ dữ liệu trùng lặp khi INSERT bảng trong MySQL / MariaDB

Bạn có 1 bảng B muốn insert vào 1 bảng A và bảng B có khá nhiều dữ liệu trùng lặp với bảng A. Khi bạn thực hiện lệnh insert sẽ xảy ra lỗi Error Code: 1062. Duplicate entry do bảng A có cột là khóa chính (PRIMARY KEY) hoặc cột đó có thuộc tính là UNIQUE.

Để thực hiện insert bảng A vào bảng B và bỏ qua những dữ liệu trùng lặp ta sử dụng lệnh INSERT IGNORE.

Ta cùng tham khảo ví dụ bằng 2 bảng sau. Đầu tiên ta tạo 2 bảng sinhvien1 và sinhvien2 và thêm dữ liệu vào 2 bảng này

DROP TABLE IF EXISTS sinhvien1;
CREATE TABLE sinhvien1(
MaSV int,
Ten varchar(50) DEFAULT NULL,
CONSTRAINT `primary_masv`PRIMARY KEY ( MaSV )
);

DROP TABLE IF EXISTS sinhvien2;
CREATE TABLE sinhvien2(
MaSV int,
Ten varchar(50) DEFAULT NULL,
CONSTRAINT `primary_masv`PRIMARY KEY ( MaSV )
);

INSERT INTO sinhvien1 (MaSV, Ten) VALUES (111, 'Nguyễn Thị Duyên');
INSERT INTO sinhvien1 (MaSV, Ten) VALUES (123, 'Trần Anh Khoa');
INSERT INTO sinhvien1 (MaSV, Ten) VALUES (124, 'Vũ Tuấn Anh');
 
INSERT INTO sinhvien2 (MaSV, Ten) VALUES (111, 'Nguyễn Thị Mỹ Duyên');
INSERT INTO sinhvien2 (MaSV, Ten) VALUES (246, 'Nguyễn Mỹ Linh');
INSERT INTO sinhvien2 (MaSV, Ten) VALUES (124, 'Trần Công Đức');

Như các bạn có thể nhìn thấy, có 1 sinh viên có mã 111 và 124 trùng lặp. Bây giờ ta sẽ insert dữ liệu bảng sinhvien2 vào dữ liệu bảng sinhvien1 bằng lệnh INSERT. Ở ví dụ dưới mình sẽ tạo 1 transaction bằng lệnh START TRANSACTION để phòng trường hợp kết quả bị sai thì mình còn ROLLBACK lại được.

START TRANSACTION;
INSERT INTO sinhvien1
SELECT * FROM sinhvien2;  -- khi chạy báo lỗi

MySQL báo lỗi Error Code: 1062. Duplicate entry ‘111’ for key ‘sinhvien1.PRIMARY’ và hủy luôn lệnh INSERT. Bây giờ ta sẽ thực hiện lệnh INSERT IGNORE.

Quảng cáo

Ủng hộ website

START TRANSACTION; 
INSERT IGNORE INTO sinhvien1
SELECT * FROM sinhvien2;

Sau khi thực hiện các query trên, MySQL cho sẽ cho insert tất cả bảng, bỏ qua hàng trùng lặp và chỉ trả về cảnh báo 1 row(s) affected, 2 warning(s): 1062 Duplicate entry ‘111’ for key ‘sinhvien1.PRIMARY’ Records: 3  Duplicates: 2  Warnings: 2

Kết quả trả về bảng sinhvien1 là:

SELECT * FROM sinhvien1;
+-----+-------------------+
|MaSV |	Ten               |
+-----+-------------------+
|111  |	Nguyễn Thị Duyên  |
|123  |	Trần Anh Khoa     |
|124  |	Vũ Tuấn Anh       |
|246  |	Nguyễn Mỹ Linh    |
+-----+-------------------+
COMMIT;   --  sau khi kiểm tra dữ liệu thấy đúng chạy lệnh này
-- ROLLBACK;  nếu không đúng chạy lệnh này

Các bạn có thể thấy kết quả sinh viên có mã 111 và 124 ở bảng sinhvien2 bị bỏ qua, không insert vào bảng sinhvien1. Sau khi kiểm tra dữ liệu không xảy ra lỗi ta chạy tiếp lệnh COMMIT để ghi dữ liệu vào database

Thay thế các dữ liệu trùng lặp sử dụng REPLACE

START TRANSACTION;
REPLACE INTO sinhvien1
SELECT * FROM sinhvien2;

MySQL trả về cảnh báo 5 row(s) affected Records: 3 Duplicates: 2 Warnings: 0 và kết quả của bảng sinhvien1 các sinh viên có mã 111 và 124 đã được được thay thế.

SELECT * FROM sinhvien1;
+-----+----------------------+
|MaSV |	Ten                  |
+-----+----------------------+
|111  |	Nguyễn Thị Mỹ Duyên  |
|123  |	Trần Anh Khoa        |
|124  |	Trần Công Đức        |
|246  |	Nguyễn Mỹ Linh       |
+-----+----------------------+

Bài viết dựa trên MySQL Document và chạy trên MySQL 8.0.26 và MariaDB 10.2. Mong được các bạn đóng góp ý kiến để website ngày càng phát triển.

Add Comment