Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

INSERT ... ON DUPLICATE KEY UPDATE with WHERE?

I'm doing a INSERT ... ON DUPLICATE KEY UPDATE but I need the update part to be conditional, only doing the update if some extra condition has changed.

However, WHERE is not allowed on this UPDATE. Is there any workaround for this?

I can't do combinations of INSERT/UPDATE/SELECT since this needs to work over a replication.

like image 390
Andreas Wederbrand Avatar asked Mar 18 '10 11:03

Andreas Wederbrand


People also ask

Can we use insert in place of update?

No. Insert will only create a new row.

What is on duplicate key?

The ON DUPLICATE KEY UPDATE clause can contain multiple column assignments, separated by commas. The use of VALUES() to refer to the new row and columns is deprecated beginning with MySQL 8.0.

How do I insert duplicate rows in SQL?

Use the context menu on the same table, to get another script: "Script Table as | SELECT To | New Query Window". This will be a totally standard select list, with all your fields listed out. Copy the whole query and paste it in over the VALUES clause in your first query window. This will give you a complete INSERT ...

Can primary key be duplicate in MySQL?

Since both primary key and unique columns do not accept duplicate values, they can be used for uniquely identifying a record in the table. This means that, for each value in the primary or unique key column, only one record will be returned.


2 Answers

I suggest you to use IF() to do that.

Refer: conditional-duplicate-key-updates-with-mysql

INSERT INTO daily_events (created_on, last_event_id, last_event_created_at)   VALUES ('2010-01-19', 23, '2010-01-19 10:23:11') ON DUPLICATE KEY UPDATE   last_event_id = IF(last_event_created_at < VALUES(last_event_created_at), VALUES(last_event_id), last_event_id); 
like image 183
LouisXIV Avatar answered Sep 20 '22 04:09

LouisXIV


This is our final solution, works like a charm!

The insert ignore will make sure that the row exists on both the master and slave, in case they've ever diverted.

The update ... where makes sure that only the most recent update, globally, is the end result after all replication is done.

mysql> desc test; +-------+--------------+------+-----+-------------------+-------+ | Field | Type         | Null | Key | Default           | Extra | +-------+--------------+------+-----+-------------------+-------+ | id    | int(11)      | NO   | PRI | NULL              |       |  | value | varchar(255) | YES  |     | NULL              |       |  | ts    | timestamp    | NO   |     | CURRENT_TIMESTAMP |       |  +-------+--------------+------+-----+-------------------+-------+  mysql> insert ignore into test values (4, "foo", now());     mysql> update test set value = "foo", ts = now() where id = 4 and ts <= now(); 
like image 42
Andreas Wederbrand Avatar answered Sep 20 '22 04:09

Andreas Wederbrand