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

เพิ่มแถวในตารางจากข้อมูลสตริงของอีกตารางใน MySQL (INSERT INTO SELECT)

คำสั่ง 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 หากข้อมูลมาจากไฟล์