INSERT ...在WHERE的重复键更新?

时间:2010-03-18 11:37:39

标签: mysql replication

我正在做INSERT ... ON DUPLICATE KEY UPDATE但是我需要更新部分是有条件的,只有在某些额外条件发生变化时才进行更新。

但是,此WHERE不允许UPDATE。有没有解决方法呢?

我无法执行INSERT / UPDATE / SELECT的组合,因为这需要在复制上工作。

6 个答案:

答案 0 :(得分:59)

我建议你使用IF()来做到这一点。

参考: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);

答案 1 :(得分:11)

这是我们的最终解决方案,就像一个魅力!

插入忽略将确保主服务器和从服务器上存在该行,以防它们转移。

更新...其中确保全部复制完成后,全局最新更新才是最终结果。

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();

答案 2 :(得分:3)

您可以使用两个插入语句..因为您可以将where子句添加到源数据的选择部分。

选择两组数据,一组用“复制”插入,另一组插入时不用“复制”。

答案 3 :(得分:0)

  

php_lock
name:idString,locked:bool,   time:时间戳,locked_by:字符串要插入或的值   更新
1,CURRENT_TIMESTAMP,'script'
其中name ='wwww'AND   locked = 2

INSERT INTO `php_lock` (`name`, locked, `time`, `locked_by`)  
(SELECT * FROM 
    (SELECT `name`,1,CURRENT_TIMESTAMP, 'script' FROM `php_lock` 
        WHERE `name`='wwww' AND `locked`=2  
    UNION (
    SELECT 'wwww',1 ,CURRENT_TIMESTAMP, 'script') 
) AS temp LIMIT 1) 
ON DUPLICATE KEY UPDATE locked=VALUES(locked), `time`=VALUES(`time`), `locked_by`=VALUES(`locked_by`);

答案 4 :(得分:0)

概述

  • AWUpsertCondy希望将之前更改为之后

SimplifiedProblemIllustration

问题

  • 如果MySQL检测到重复的主键,AWUpsertCondy不希望插入查询失败
  • MySQL不支持带有ON DUPLICATE KEY UPDATE的条件WHERE子句

解决方案

  • MySQL通过IF()函数支持条件子句
  • 这里我们有一个简单的条件,仅更新用户标识小于9的那些项目。
INSERT INTO zzdemo_table02
    (lname,userid)
  SELECT
    lname,userid
    FROM(
      SELECT
        lname,userid
      FROM
        zzdemo_table01
    ) as tt01
ON DUPLICATE KEY UPDATE
    userid=IF(@doupdate:=IF( (tt01.userid < 9) , True, False), 
        tt01.userid, zzdemo_table02.userid)
    ,lname=IF(@doupdate, tt01.lname , zzdemo_table02.lname )
;

陷阱

  • 我们引入了一个MySQL变量@doupdate,以标记UPDATE行是否满足条件。然后,对于在UPDATE语句中使用的所有数据库列,都使用相同的变量
  • 在第一个条件中,我们都声明变量并确定条件是否适用。可以说,这种方法比WHERE子句更麻烦

另请参见

答案 5 :(得分:-1)

On duplicate key不允许我们使用where子句,因此有两种方法可以实现相同的目的。

  1. 如果你知道大多数时候你会得到重复的密钥,那么

    a. Update the table first using update query and where clause b. If update fails then insert the record into table using insert query

  2. 如果你知道大多数时候你要插入表格,那么

    a. Insert the record into table using insert ignore query - what it does is actually ignore the insert if duplicate key found b. If insert ignore fails then update the record using update query

  3. insert ignore click here

    参考