Câu lệnh INSERT INTO ... SELECT cho phép sao chép dữ liệu từ bảng này sang bảng khác trong một truy vấn duy nhất, hỗ trợ lọc, biến đổi dữ liệu trên đường bay.
Cú pháp
INSERT INTO bang_dich (cot1, cot2, ...) SELECT cot1, cot2, ... FROM bang_nguon WHERE dieu_kien_loc;
Ví dụ minh họa
Bảng nguồn DemoTable1 có dữ liệu thô (có NULL):
CREATE TABLE DemoTable1 (Id INT, FirstName VARCHAR(20)); INSERT INTO DemoTable1 VALUES (101, 'Chris'), (NULL, 'Bob'), (NULL, NULL), (102, 'David');
Tạo bảng đích DemoTable2:
CREATE TABLE DemoTable2 (StudentId INT, StudentName VARCHAR(20));
Chèn chỉ các hàng có cả Id và FirstName không NULL:
INSERT INTO DemoTable2 (StudentId, StudentName) SELECT Id, FirstName FROM DemoTable1 WHERE Id IS NOT NULL AND FirstName IS NOT NULL;
Kết quả
| StudentId | StudentName |
|---|---|
| 101 | Chris |
| 102 | David |
Các trường hợp sử dụng phổ biến
- Backup/Archive:
INSERT INTO archive_table SELECT * FROM main_table WHERE created_at < '2023-01-01' - ETL/Transform:
INSERT INTO dim_table SELECT DISTINCT UPPER(name), ... FROM staging - Tạo bảng mới từ truy vấn:
CREATE TABLE new_table AS SELECT ...(MySQL hỗ trợ)
Lưu ý quan trọng
- Số cột và kiểu dữ liệu trong
SELECTphải khớp vớiINSERT INTO. - Có thể dùng biểu thức, hàm, hằng số trong SELECT:
SELECT id, UPPER(name), NOW() FROM ... - Tránh
INSERT INTO t SELECT * FROM t(gây trùng lặp vô hạn nếu không có LIMIT/WHERE). - Với bảng lớn, cân nhắc
INSERT IGNOREhoặcON DUPLICATE KEY UPDATEđể xử lý trùng khóa.