คำสั่ง INSERT ... ON DUPLICATE KEY UPDATE (Upsert)
ทำงานแบบ: **ลอง Insert ก่อน → หากเจอ Duplicate Key (PK/Unique) ให้ Update แทน** เหมาะสำหรับ Sync Data, Counter, Cache
Syntax
INSERT INTO table (col1, col2, ...) VALUES (val1, val2, ...) ON DUPLICATE KEY UPDATE col2 = new_val, col3 = new_val, ...;
ตัวอย่าง: Unique Key บน StudentName
สร้างตารางมี Unique Key บน StudentName:
mysql> CREATE TABLE DemoTable733 (
StudentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
StudentName VARCHAR(100),
StudentMarks INT,
UNIQUE KEY Un_Name (StudentName)
);
Query OK, 0 rows affected (0.60 sec)
Insert ครั้งแรก (John, Adam, Carol) - ทั้งหมด Insert ใหม่:
mysql> INSERT INTO DemoTable733 (StudentName, StudentMarks) VALUES
('John', 45) ON DUPLICATE KEY UPDATE StudentMarks = 86;
Query OK, 1 row affected (0.19 sec)
mysql> INSERT INTO DemoTable733 (StudentName, StudentMarks) VALUES
('Adam', 65) ON DUPLICATE KEY UPDATE StudentMarks = 86;
Query OK, 1 row affected (0.15 sec)
mysql> INSERT INTO DemoTable733 (StudentName, StudentMarks) VALUES
('Carol', 75) ON DUPLICATE KEY UPDATE StudentMarks = 86;
Query OK, 1 row affected (0.08 sec)
Insert ซ้ำ (John อีกครั้ง) → **Update** StudentMarks = 86:
mysql> INSERT INTO DemoTable733 (StudentName, StudentMarks) VALUES
('John', 45) ON DUPLICATE KEY UPDATE StudentMarks = 86;
Query OK, 2 rows affected (0.12 sec)
ผลลัพธ์ - John มี Marks = 86 (Updated), Adam/Carry คงค่า Insert เดิม:
mysql> SELECT * FROM DemoTable733;
+-----------+-------------+--------------+ | StudentId | StudentName | StudentMarks | +-----------+-------------+--------------+ | 1 | John | 86 | | 2 | Adam | 65 | | 3 | Carol | 75 | +-----------+-------------+--------------+ 3 rows in set (0.00 sec)
จุดสำคัญ
- ต้องมี **Primary Key** หรือ **Unique Index** ถึงจะ Trigger Duplicate
VALUES(col)ในส่วน UPDATE = ค่าที่พยายาม Insert (ไม่ใช่ค่าเก่า):ON DUPLICATE KEY UPDATE StudentMarks = VALUES(StudentMarks) + 10;
- คืนค่า Rows Affected: 1 = Insert, 2 = Update, 0 = No Change (หากค่าเหมือนเดิมและ MySQL Optimize)
- หลายแถวพร้อมกัน:
INSERT INTO t (a,b) VALUES (1,2),(2,3),(3,4) ON DUPLICATE KEY UPDATE b=VALUES(b);
INSERT IGNORE vs ON DUPLICATE KEY UPDATE
| คำสั่ง | พฤติกรรมเมื่อ Duplicate |
|---|---|
| INSERT IGNORE | ข้ามไป (Silent), ไม่ Error, ไม่ Update |
| ON DUPLICATE KEY UPDATE | Update คอลัมน์ที่ระบุ |
| REPLACE INTO | Delete แถวเก่า + Insert ใหม่ (Auto Increment เปลี่ยน) |
MySQL 8.0.19+: INSERT ... ON DUPLICATE KEY UPDATE ... WHERE
INSERT ... ON DUPLICATE KEY UPDATE col = new_val WHERE some_condition;