Search code examples
mysqlsqlpdo

Conditional ON DUPLICATE KEY UPDATE (Update only if certain condition is true)


I have the following query being used:

INSERT INTO userlist (username, lastupdate, programruncount, ip)
VALUES (:username, NOW(), 1, :ip)
ON DUPLICATE KEY UPDATE
lastupdate = NOW(), programruncount = programruncount + 1, ip = :ip;

However, I also want to make the ON DUPLICATE KEY UPDATE conditional, so it will do the following:

  • IF lastupdate was less than 20 minutes ago (lastupdate > NOW() - INTERVAL 20 MINUTE).
  • True: Update lastupdate = NOW(), add one to programruncount and then update ip = :ip.
  • False: All fields should be left the same.

I am not really sure how I would do this but after looking around, I tried using an IF Statement in the ON DUPLICATE KEY UPDATE part.

INSERT INTO userlist (username, lastupdate, programruncount, ip)
VALUES ("testuser", NOW(), "1", "127.0.0.1")
ON DUPLICATE KEY UPDATE
IF(lastupdate > NOW() - INTERVAL 20 MINUTE, VALUES(lastupdate, programruncount + 1),
lastupdate, programruncount);

However I am getting the following error: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF(lastupdate > NOW() - INTERVAL 20 MINUTE, VALUES(lastupdate, programruncount +' at line 6


Solution

  • you're using IF statement and VALUES() function incorrectly

    INSERT INTO userlist (username, lastupdate, programruncount, ip)
    VALUES (:username, NOW(), 1, :ip)
    ON DUPLICATE KEY UPDATE
    lastupdate = IF(NOW() > lastupdate + INTERVAL 20 MINUTE, NOW(), lastupdate),
    programruncount = IF(NOW() > lastupdate + INTERVAL 20 MINUTE, programruncount + 1,   programruncount),
    ip = IF(NOW() > lastupdate + INTERVAL 20 MINUTE, VALUES(ip), ip);
    

    so IF checks for a condition and return one of two values provided as its parameters. See MySQL's Flow Control Operators.