การเตรียมตารางต้นทาง
mysql> CREATE TABLE DemoTable1879 (
Id INT, Name VARCHAR(20)
);
mysql> INSERT INTO DemoTable1879 VALUES
(101, 'Chris Brown'), (102, 'David Miller'), (103, 'Adam Smith');
สร้างตารางปลายทาง
mysql> CREATE TABLE DemoTable1880 (
ClientId INT, ClientName VARCHAR(20)
);
คัดลอกข้อมูลเฉพาะ Id 101 และ 103
mysql> INSERT INTO DemoTable1880(ClientId, ClientName)
SELECT Id, Name FROM DemoTable1879 WHERE Id IN (101, 103);
Query OK, 2 rows affected
ผลลัพธ์
mysql> SELECT * FROM DemoTable1880;
+----------+-------------+
| ClientId | ClientName |
+----------+-------------+
| 101 | Chris Brown |
| 103 | Adam Smith |
+----------+-------------+
รูปแบบ INSERT ... SELECT
INSERT INTO target_table (col1, col2, ...)
SELECT col1, col2, ... FROM source_table
WHERE condition;
จุดสำคัญ
- จำนวนคอลัมน์และลำดับต้องตรงกัน (หรือระบุ Column List ชัดเจน)
- ชนิดข้อมูลต้องเข้ากันได้ (Type Compatibility)
- Auto Increment ใน Target: ใส่ NULL หรือไม่ระบุคอลัมน์นั้น
- ทำงานใน Transaction เดียว (Atomic)
ตัวอย่างเพิ่มเติม
-- คัดลอกทั้งตาราง (Schema + Data)
CREATE TABLE new_table AS SELECT * FROM old_table;
-- คัดลอกเฉพาะ Schema (No Data)
CREATE TABLE new_table LIKE old_table;
-- หรือ
CREATE TABLE new_table AS SELECT * FROM old_table WHERE 1=0;
-- คัดลอกพร้อม Transform
INSERT INTO target (id, full_name, created_at)
SELECT id, CONCAT(first_name, ' ', last_name), NOW()
FROM source WHERE active = 1;
-- คัดลอกระหว่าง Database
INSERT INTO db2.table SELECT * FROM db1.table;
Performance Tips
- Batch Size: แบ่งเป็น Chunk (LIMIT 1000) ถ้าข้อมูลเยอะ
- Disable Index/Keys ชั่วคราว (MyISAM) หรือลด Overhead (InnoDB)
- ใช้
INSERT IGNORE หรือ ON DUPLICATE KEY UPDATE จัดการ Duplicate