Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

MySQL INSERT INTO ... SELECT คัดลอกข้อมูลระหว่างตาราง

คัดลอกข้อมูลจากตารางหนึ่งไปอีกตารางด้วย 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    |
+-------+

กรณีใช้งานจริง

ScenarioQuery Pattern
Backup TableCREATE TABLE backup AS SELECT * FROM source;
Archive Old DataINSERT INTO archive SELECT * FROM orders WHERE created_at < '2023-01-01';
Transform & LoadINSERT INTO dim_table SELECT id, UPPER(name), YEAR(dob) FROM staging;
Merge (Upsert)INSERT ... SELECT ... ON DUPLICATE KEY UPDATE ...
Partition MaintenanceINSERT 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';

ข้อควรระวัง

  1. Column Count & Order ต้องตรงกัน - ระบุ Column List เสมอ (INSERT INTO t (a,b) SELECT x,y ...)
  2. Data Type Compatible - Source → Target ต้อง Cast ได้ (VARCHAR → INT อาจ Error)
  3. Auto Increment: Target Table ถ้ามี AI Column ให้เว้นไว้ (INSERT ไม่ระบุค่า)
  4. Transaction: ใช้ BEGIN/COMMIT สำหรับข้อมูลเยอะ
  5. 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);