การเตรียมตาราง: Unique Key
mysql> CREATE TABLE DemoTable1891 (
FirstName VARCHAR(20),
UNIQUE KEY(FirstName)
);
INSERT ON DUPLICATE KEY UPDATE
mysql> INSERT INTO DemoTable1891 VALUES('Chris')
ON DUPLICATE KEY UPDATE FirstName = 'Robert'; -- Insert ใหม่
Query OK, 1 row affected
mysql> INSERT INTO DemoTable1891 VALUES('David')
ON DUPLICATE KEY UPDATE FirstName = 'Robert'; -- Insert ใหม่
Query OK, 1 row affected
mysql> INSERT INTO DemoTable1891 VALUES('Chris')
ON DUPLICATE KEY UPDATE FirstName = 'Robert'; -- Duplicate! Update แทน
Query OK, 2 rows affected
ผลลัพธ์ (Chris กลายเป็น Robert)
mysql> SELECT * FROM DemoTable1891;
+-----------+
| FirstName |
+-----------+
| David |
| Robert |
+-----------+
การทำงาน
- พยายาม Insert
- ถ้า Unique Key/Primary Key ชน → Trigger ON DUPLICATE KEY UPDATE
- Execute UPDATE Clause แทน
- Rows Affected: 1 = Insert, 2 = Update
Syntax
INSERT INTO table (cols) VALUES (vals)
ON DUPLICATE KEY UPDATE col1 = val1, col2 = val2, ...;
ใช้ VALUES() อ้างอิงค่าที่ Insert
INSERT INTO users (id, name, email, login_count)
VALUES (1, 'John', 'john@email.com', 1)
ON DUPLICATE KEY UPDATE
login_count = login_count + 1,
last_login = NOW(); -- ใช้ค่าปัจจุบัน ไม่ใช่ VALUES()
กรณีใช้งานจริง
- Upsert (Insert หรือ Update)
- Counter:
visits = visits + 1
- Last Seen:
last_seen = NOW()
- Merge Data จาก External Source
ข้อจำกัด
- ต้องมี Primary Key หรือ Unique Index
- Multiple Unique Keys: Trigger ถ้า Key ใด Key หนึ่งชน
- Auto Increment: ค่าเพิ่มแม้จะ Update (Gap ใน Sequence)
- Replication: Statement-based อาจต่าง Node
Alternative: REPLACE INTO
REPLACE INTO DemoTable1891 VALUES('Chris'); -- DELETE + INSERT
-- ต่างจาก ON DUPLICATE KEY: ไม่รักษาคอลัมน์อื่น