snippetsqlMinor
How to use ON DUPLICATE KEY for UPDATE
Viewed 0 times
updateduplicateforhowusekey
Problem
Consider a table of
Updating the value of number as
or
Since external_id-number couple is unique, it will not update if the new value of number exists.
How can I use something like
CREATE TABLE test
(
id int(11) unsigned NOT NULL AUTO_INCREMENT,
external_id int(11),
number smallint(5),
value varchar(255),
UNIQUE INDEX (external_id, number),
PRIMARY KEY(id)
) ENGINE=InnoDBUpdating the value of number as
UPDATE test SET number=number + 1 WHERE external_id='X'or
UPDATE test SET number='Y' WHERE external_id='X'Since external_id-number couple is unique, it will not update if the new value of number exists.
How can I use something like
INSERT ... ON DUPLICATE KEY to increase the value of number by number + 1 to reach an available value according to the UNIQUE Constraint and complete the UPDATE task?Solution
First a sample table
Let's insert an initial row and SELECT it back
Let's insert the same thing again
OK let's try the value column at the same time
This time change value and number
Hope this helps.
Give it a Try !!!
mysql> drop database if exists ali;
Query OK, 1 row affected (0.10 sec)
mysql> create database ali;
Query OK, 1 row affected (0.00 sec)
mysql> use ali;
Database changed
mysql> CREATE TABLE test
-> (
-> id int(11) unsigned NOT NULL AUTO_INCREMENT,
-> external_id int(11),
-> number smallint(5),
-> value varchar(255),
-> UNIQUE INDEX (external_id, number),
-> PRIMARY KEY(id)
-> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.09 sec)
mysql>Let's insert an initial row and SELECT it back
mysql> INSERT INTO test (external_id,number,value)
-> VALUES (200,15,'Y')
-> ON DUPLICATE KEY UPDATE number = number + 1;SELECT * FROM test;
Query OK, 1 row affected (0.06 sec)
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 15 | Y |
+----+-------------+--------+-------+
1 row in set (0.00 sec)
mysql>Let's insert the same thing again
mysql> INSERT INTO test (external_id,number,value)
-> VALUES (200,15,'Y')
-> ON DUPLICATE KEY UPDATE number = number + 1;SELECT * FROM test;
Query OK, 2 rows affected (0.10 sec)
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 16 | Y |
+----+-------------+--------+-------+
1 row in set (0.00 sec)
mysql>OK let's try the value column at the same time
mysql> INSERT INTO test (external_id,number,value)
-> VALUES (201,15,'X')
-> ON DUPLICATE KEY UPDATE
-> number = number + 1,value = VALUES(value);
Query OK, 1 row affected (0.07 sec)
mysql> SELECT * FROM test;
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 16 | Y |
| 5 | 201 | 15 | X |
+----+-------------+--------+-------+
2 rows in set (0.00 sec)
mysql> INSERT INTO test (external_id,number,value)
-> VALUES (201,15,'X')
-> ON DUPLICATE KEY UPDATE
-> number = number + 1,value = VALUES(value);
Query OK, 2 rows affected (0.06 sec)
mysql> SELECT * FROM test;
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 16 | Y |
| 5 | 201 | 16 | X |
+----+-------------+--------+-------+
2 rows in set (0.00 sec)
mysql>This time change value and number
mysql> INSERT INTO test (external_id,number,value)
-> VALUES (202,15,'Z')
-> ON DUPLICATE KEY UPDATE
-> number = number + 1,
-> value = VALUES(value);
Query OK, 1 row affected (0.07 sec)
mysql> SELECT * FROM test;
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 16 | Y |
| 5 | 201 | 16 | X |
| 8 | 202 | 15 | Z |
+----+-------------+--------+-------+
3 rows in set (0.00 sec)
mysql> INSERT INTO test (external_id,number,value)
-> VALUES (202,15,'A')
-> ON DUPLICATE KEY UPDATE
-> number = number + 1,
-> value = VALUES(value);
Query OK, 2 rows affected (0.07 sec)
mysql> SELECT * FROM test;
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 16 | Y |
| 5 | 201 | 16 | X |
| 8 | 202 | 16 | A |
+----+-------------+--------+-------+
3 rows in set (0.00 sec)
mysql>Hope this helps.
Give it a Try !!!
Code Snippets
mysql> drop database if exists ali;
Query OK, 1 row affected (0.10 sec)
mysql> create database ali;
Query OK, 1 row affected (0.00 sec)
mysql> use ali;
Database changed
mysql> CREATE TABLE test
-> (
-> id int(11) unsigned NOT NULL AUTO_INCREMENT,
-> external_id int(11),
-> number smallint(5),
-> value varchar(255),
-> UNIQUE INDEX (external_id, number),
-> PRIMARY KEY(id)
-> ) ENGINE=InnoDB;
Query OK, 0 rows affected (0.09 sec)
mysql>mysql> INSERT INTO test (external_id,number,value)
-> VALUES (200,15,'Y')
-> ON DUPLICATE KEY UPDATE number = number + 1;SELECT * FROM test;
Query OK, 1 row affected (0.06 sec)
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 15 | Y |
+----+-------------+--------+-------+
1 row in set (0.00 sec)
mysql>mysql> INSERT INTO test (external_id,number,value)
-> VALUES (200,15,'Y')
-> ON DUPLICATE KEY UPDATE number = number + 1;SELECT * FROM test;
Query OK, 2 rows affected (0.10 sec)
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 16 | Y |
+----+-------------+--------+-------+
1 row in set (0.00 sec)
mysql>mysql> INSERT INTO test (external_id,number,value)
-> VALUES (201,15,'X')
-> ON DUPLICATE KEY UPDATE
-> number = number + 1,value = VALUES(value);
Query OK, 1 row affected (0.07 sec)
mysql> SELECT * FROM test;
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 16 | Y |
| 5 | 201 | 15 | X |
+----+-------------+--------+-------+
2 rows in set (0.00 sec)
mysql> INSERT INTO test (external_id,number,value)
-> VALUES (201,15,'X')
-> ON DUPLICATE KEY UPDATE
-> number = number + 1,value = VALUES(value);
Query OK, 2 rows affected (0.06 sec)
mysql> SELECT * FROM test;
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 16 | Y |
| 5 | 201 | 16 | X |
+----+-------------+--------+-------+
2 rows in set (0.00 sec)
mysql>mysql> INSERT INTO test (external_id,number,value)
-> VALUES (202,15,'Z')
-> ON DUPLICATE KEY UPDATE
-> number = number + 1,
-> value = VALUES(value);
Query OK, 1 row affected (0.07 sec)
mysql> SELECT * FROM test;
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 16 | Y |
| 5 | 201 | 16 | X |
| 8 | 202 | 15 | Z |
+----+-------------+--------+-------+
3 rows in set (0.00 sec)
mysql> INSERT INTO test (external_id,number,value)
-> VALUES (202,15,'A')
-> ON DUPLICATE KEY UPDATE
-> number = number + 1,
-> value = VALUES(value);
Query OK, 2 rows affected (0.07 sec)
mysql> SELECT * FROM test;
+----+-------------+--------+-------+
| id | external_id | number | value |
+----+-------------+--------+-------+
| 1 | 200 | 16 | Y |
| 5 | 201 | 16 | X |
| 8 | 202 | 16 | A |
+----+-------------+--------+-------+
3 rows in set (0.00 sec)
mysql>Context
StackExchange Database Administrators Q#15589, answer score: 5
Revisions (0)
No revisions yet.