คัดลอกข้อมูลจากตารางหนึ่งไปอีกตารางด้วย INSERT ... SELECT
Syntax มาตรฐานที่รองรับในทุก Version:
INSERT INTO target_table (col1, col2, ...)
SELECT col1, col2, ... FROM source_table
WHERE condition;
ตัวอย่างเต็ม
-- ตารางต้นทาง
CREATE TABLE DemoTabe1 (Marks INT);
INSERT INTO DemoTabe1 VALUES (68), (89), (99), (39), (49);
-- ตารางปลายทาง
CREATE TABLE DemoTabe2 (Score INT);
-- คัดลอกข้อมูล
INSERT INTO DemoTabe2 (Score)
SELECT Marks FROM DemoTabe1;
ผลลัพธ์: DemoTabe2 มีข้อมูลเหมือน DemoTabe1 ทุกแถว
+-------+
| Score |
+-------+
| 68 |
| 89 |
| 99 |
| 39 |
| 49 |
+-------+
กรณีใช้งานจริง
| Scenario | Query Pattern |
|---|---|
| Backup Table | CREATE TABLE backup AS SELECT * FROM source; |
| Archive Old Data | INSERT INTO archive SELECT * FROM orders WHERE created_at < '2023-01-01'; |
| Transform & Load | INSERT INTO dim_table SELECT id, UPPER(name), YEAR(dob) FROM staging; |
| Merge (Upsert) | INSERT ... SELECT ... ON DUPLICATE KEY UPDATE ... |
| Partition Maintenance | INSERT INTO part_2024 SELECT * FROM staging WHERE year=2024; |
ตัวอย่าง Advance: Transform ระหว่าง Copy
INSERT INTO user_summary (user_id, full_name, age, created_year)
SELECT
id,
CONCAT(first_name, ' ', last_name),
TIMESTAMPDIFF(YEAR, dob, CURDATE()),
YEAR(created_at)
FROM users
WHERE status = 'active';
ข้อควรระวัง
- Column Count & Order ต้องตรงกัน - ระบุ Column List เสมอ (INSERT INTO t (a,b) SELECT x,y ...)
- Data Type Compatible - Source → Target ต้อง Cast ได้ (VARCHAR → INT อาจ Error)
- Auto Increment: Target Table ถ้ามี AI Column ให้เว้นไว้ (INSERT ไม่ระบุค่า)
- Transaction: ใช้ BEGIN/COMMIT สำหรับข้อมูลเยอะ
- Locking: SELECT จะ Lock Row (InnoDB) - ใช้
LOCK IN SHARE MODEหรือFOR UPDATEถ้าต้องการ
Performance: บนตารางใหญ่
- ใช้
INSERT ... SELECTแบบ Chunk (LIMIT 10000 ต่อ Batch) - Disable Index/Keys ชั่วคราว:
ALTER TABLE target DISABLE KEYS(MyISAM) / ไม่ได้ใน InnoDB - พิจารณา
LOAD DATA INFILEสำหรับ Import จาก File (เร็วกว่ามาก)
MySQL 8.0.19+: INSERT ... ON DUPLICATE KEY UPDATE
INSERT INTO target (id, val)
SELECT id, val FROM source
ON DUPLICATE KEY UPDATE val = VALUES(val);