Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

INSERT INTO … ON DUPLICATE KEY UPDATE …. with condition?

I am still wondering if there is something like a conditional on duplicate update in MySQL 5.7

I have a table which is updated by different sources.

Let’s assume I have a table

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

CREATE TABLE t 
(
    name VARCHAR(100),
    value INT,
    last update DATETIME
)

I have 3 rows

name value lastupdate
a 10 2021-01-01
b 20 2021-02-01
c 30 2021-03-01

Now I have some data to be imported

name value lastupdate
a 20 2021-01-01
b 40 2021-01-01
c 60 2021-04-01

The result of the query should be

name value lastupdate
a 20 2021-01-01
b 20 2021-02-01
c 60 2021-03-01

Can this be done by one insert query or must I check first if the last update of the existing data in the table is newer then the date of the import data?

>Solution :

Assuming that name is the PRIMARY KEY of the table or is defined as UNIQUE, you can use a CASE expression:

INSERT INTO t (name, value, lastupdate) VALUES
  ('a', 20, '2021-01-01'),
  ('b', 40, '2021-01-01'),
  ('c', 60, '2021-04-01')
ON DUPLICATE KEY UPDATE
value = CASE WHEN VALUES(lastupdate) >= lastupdate THEN VALUES(value) ELSE value END;

See the demo.

Note that (from INSERT … ON DUPLICATE KEY UPDATE Statement):

The use of VALUES() to refer to the new row and columns is deprecated
beginning with MySQL 8.0.20, and is subject to removal in a future
version of MySQL. Instead, use row and column aliases, as described in
the next few paragraphs of this section.

So, if your version of MySql is 8.0.20+ it is recommended to use an alias instead of VALUES():

INSERT INTO t (name, value, lastupdate) VALUES
  ('a', 20, '2021-01-01'),
  ('b', 40, '2021-01-01'),
  ('c', 60, '2021-04-01') AS new
ON DUPLICATE KEY UPDATE
t.value = CASE WHEN new.lastupdate >= t.lastupdate THEN new.value ELSE t.value END;

See the demo.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading