คำสั่ง INSERT INTO SELECT
ใช้คัดลอกข้อมูลจากตารางหนึ่งไปอีกตารางหนึ่งในคำสั่งเดียว โดยสามารถกรองข้อมูลด้วย WHERE, จัดรูปแบบด้วย Function, หรือ Join หลายตารางได้
รูปแบบคำสั่ง
INSERT INTO target_table (col1, col2, ...) SELECT col1, col2, ... FROM source_table WHERE condition;
ตัวอย่างการใช้งาน
1. สร้างตารางต้นทาง (DemoTable1)
mysql> CREATE TABLE DemoTable1 (
-> Id INT,
-> FirstName VARCHAR(20)
-> );
Query OK, 0 rows affected (0.71 sec)
2. เพิ่มข้อมูล (มีค่า NULL ปนอยู่)
mysql> INSERT INTO DemoTable1 VALUES(101, 'Chris'); Query OK, 1 row affected (0.11 sec) mysql> INSERT INTO DemoTable1 VALUES(NULL, 'Bob'); Query OK, 1 row affected (0.19 sec) mysql> INSERT INTO DemoTable1 VALUES(NULL, NULL); Query OK, 1 row affected (0.12 sec) mysql> INSERT INTO DemoTable1 VALUES(102, 'David'); Query OK, 1 row affected (0.20 sec)
3. สร้างตารางปลายทาง (DemoTable2)
mysql> CREATE TABLE DemoTable2 (
-> StudentId INT,
-> StudentName VARCHAR(20)
-> );
Query OK, 0 rows affected (1.10 sec)
4. คัดลอกเฉพาะแถวที่ Id และ FirstName ไม่ใช่ NULL
mysql> INSERT INTO DemoTable2
-> SELECT Id, FirstName FROM DemoTable1
-> WHERE Id IS NOT NULL AND FirstName IS NOT NULL;
Query OK, 2 rows affected (0.17 sec)
Records: 2 Duplicates: 0 Warnings: 0
5. ตรวจสอบผลลัพธ์
mysql> SELECT * FROM DemoTable2;
ผลลัพธ์:
+-----------+-------------+ | StudentId | StudentName | +-----------+-------------+ | 101 | Chris | | 102 | David | +-----------+-------------+ 2 rows in set (0.00 sec)
ฟีเจอร์เพิ่มเติม
เปลี่ยนชื่อคอลัมน์ / คำนวณค่าใหม่
INSERT INTO TargetTable (FullName, YearOfBirth) SELECT CONCAT(FirstName, ' ', LastName), YEAR(BirthDate) FROM SourceTable;
รวมข้อมูลจากหลายตาราง (JOIN)
INSERT INTO OrderSummary (CustomerName, TotalOrders, TotalAmount) SELECT c.Name, COUNT(o.Id), SUM(o.Amount) FROM Customers c JOIN Orders o ON c.Id = o.CustomerId GROUP BY c.Id, c.Name;
ใช้กับ Duplicate Handling
INSERT INTO TargetTable (Id, Name) SELECT Id, Name FROM SourceTable ON DUPLICATE KEY UPDATE Name = VALUES(Name);
ข้อดี
- Atomic operation - เร็วกว่า SELECT แล้ว Loop INSERT ใน Application
- ลด Network Round-trip
- รองรับ Transaction (Rollback ได้หากผิดพลาด)
- ทำได้ใน SQL เดียว ไม่ต้องเขียน Code เพิ่ม
ข้อควรระวัง
- Data Type ต้องเข้ากัน (หรือ Cast ให้ถูกต้อง)
- Column Count และ Order ต้องตรงกัน (แนะนำระบุ Column Name ทั้งสองฝั่ง)
- Auto Increment Column: ไม่ต้องระบุใน SELECT (ให้ DB สร้างเอง)
- Foreign Key / Constraint ต้องผ่านการตรวจสอบ