คำสั่ง INSERT INTO SELECT
INSERT INTO target_table (col1, col2, ...)
SELECT col1, col2, ... FROM source_table
WHERE condition;
ตัวอย่าง: demo61 (ต้นทาง) → demo62 (ปลายทาง)
CREATE TABLE demo61 (
id INT,
name VARCHAR(20)
);
INSERT INTO demo61 VALUES
(1, 'John'), (2, 'David'), (1, 'Mike'), (2, 'Carol'), (2, 'Bob');
ข้อมูลต้นทาง
+------+-------+
| id | name |
+------+-------+
| 1 | John |
| 2 | David |
| 1 | Mike |
| 2 | Carol |
| 2 | Bob |
+------+-------+
สร้างตารางปลายทาง (มี AUTO_INCREMENT)
CREATE TABLE demo62 (
employee_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
employee_name VARCHAR(20)
);
คำสั่งคัดลอก: เฉพาะ id = 2
INSERT INTO demo62 (employee_name)
SELECT name FROM demo61 WHERE id = 2;
ผลลัพธ์: employee_id ถูกสร้างอัตโนมัติ
+-------------+---------------+
| employee_id | employee_name |
+-------------+---------------+
| 1 | David |
| 2 | Carol |
| 3 | Bob |
+-------------+---------------+
รูปแบบต่างๆ ของ INSERT INTO SELECT
1. คัดลอกทุกคอลัมน์ (โครงสร้างเหมือนกัน)
INSERT INTO target_table SELECT * FROM source_table;
2. คัดลอกบางคอลัมน์ + ค่าคงที่
INSERT INTO demo62 (employee_name, department)
SELECT name, 'IT' FROM demo61 WHERE id = 2;
3. ใช้ JOIN ใน SELECT
INSERT INTO summary (dept_name, emp_count)
SELECT d.name, COUNT(*) FROM employees e
JOIN departments d ON e.dept_id = d.id
GROUP BY d.name;
4. IGNORE ข้าม Duplicate Key
INSERT IGNORE INTO demo62 (employee_name)
SELECT name FROM demo61 WHERE id = 2;
5. ON DUPLICATE KEY UPDATE (Upsert)
INSERT INTO demo62 (employee_id, employee_name)
SELECT id, name FROM demo61
ON DUPLICATE KEY UPDATE employee_name = VALUES(employee_name);
ข้อควรระวัง
- จำนวนคอลัมน์ใน SELECT ต้องตรงกับ INSERT column list
- ชนิดข้อมูลต้องเข้ากันได้ (Implicit conversion อาจเกิด warning)
- TRIGGER บน target_table จะทำงาน
- AUTO_INCREMENT จะสร้างค่าใหม่ ไม่นำมาจาก source
- LOCKING: INSERT ... SELECT อาจล็อกตารางต้นทาง (ขึ้นกับ Isolation Level)
ประสิทธิภาพ: ตารางใหญ่
- ใช้
LIMIT แบ่ง batch: INSERT ... SELECT ... LIMIT 10000
- ปิด INDEX ชั่วคราว:
ALTER TABLE target DISABLE KEYS (MyISAM) / โหลดแล้ว REBUILD (InnoDB)
- พิจารณา
LOAD DATA INFILE หากข้อมูลมาจากไฟล์