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

MySQL INSERT INTO SELECT: คัดลอกข้อมูลจากตารางอื่น

คำสั่ง INSERT INTO SELECT

INSERT INTO target_table (col1, col2, ...)
SELECT col1, col2, ... FROM source_table
WHERE condition;

ตัวอย่าง: demo82 → demo83

CREATE TABLE demo82 (id INT, name VARCHAR(20));
INSERT INTO demo82 VALUES
(100, 'John'), (101, 'Bob'), (101, 'David'), (101, 'Mike'), (100, 'Sam');

ข้อมูลต้นทาง

+------+-------+
| id   | name  |
+------+-------+
| 100  | John  |
| 101  | Bob   |
| 101  | David |
| 101  | Mike  |
| 100  | Sam   |
+------+-------+

สร้างตารางปลายทาง

CREATE TABLE demo83 (id INT, username VARCHAR(20));

คำสั่ง: คัดลอกเฉพาะ id = 101

INSERT INTO demo83 (id, username)
SELECT id, name FROM demo82 WHERE id = 101;

ผลลัพธ์

+------+----------+
| id   | username |
+------+----------+
| 101  | Bob      |
| 101  | David    |
| 101  | Mike     |
+------+----------+

รูปแบบต่างๆ

1. คัดลอกทั้งตาราง (โครงสร้างเหมือนกัน)

INSERT INTO demo83 SELECT * FROM demo82;

2. คัดลอก + เพิ่มค่าคงที่

INSERT INTO demo83 (id, username, source)
SELECT id, name, 'demo82' FROM demo82 WHERE id = 101;

3. ใช้ JOIN ใน SELECT

INSERT INTO summary (dept_id, dept_name, emp_count)
SELECT d.id, d.name, COUNT(*) 
FROM employees e
JOIN departments d ON e.dept_id = d.id
GROUP BY d.id, d.name;

4. INSERT IGNORE (ข้าม Duplicate Key)

INSERT IGNORE INTO demo83 (id, username)
SELECT id, name FROM demo82;

5. ON DUPLICATE KEY UPDATE (Upsert)

INSERT INTO demo83 (id, username)
SELECT id, name FROM demo82
ON DUPLICATE KEY UPDATE username = VALUES(username);

6. CREATE TABLE ... AS SELECT (CTAS)

CREATE TABLE demo83_copy AS
SELECT * FROM demo82 WHERE id = 101;

สร้างตารางใหม่พร้อมข้อมูลใน 1 คำสั่ง (ไม่ Copy Index/Constraints)

ข้อควรระวัง

  • จำนวนและชนิดคอลัมน์ SELECT ต้องตรง INSERT Column List
  • AUTO_INCREMENT ใน Target: จะสร้างค่าใหม่ (ไม่นำมาจาก Source)
  • Trigger บน Target จะทำงานต่อแถว
  • Binary Log: เขียนเป็น Row-based (แต่ละแถว)
  • Locking: อาจ Lock Source Table (ขึ้นกับ Isolation Level)

ประสิทธิภาพ: ตารางใหญ่

  • Batch ด้วย LIMIT: INSERT ... SELECT ... LIMIT 10000 วน Loop
  • Disable Index ชั่วคราว (MyISAM) / Rebuild หลังโหลด (InnoDB)
  • พิจารณา LOAD DATA INFILE หาก Source เป็นไฟล์
  • Partitioning / Sharding สำหรับข้อมูลมหาศาล