我正在进行一个INSERT ... ON DUPLICATE KEY UPDATE
,但我需要更新部分有条件,只有在某些额外条件改变时才执行更新。
然而,对于这个UPDATE
,不允许使用WHERE
语句。是否有任何解决办法?
我无法进行INSERT/UPDATE/SELECT的组合操作,因为这需要在复制过程中工作。
我正在进行一个INSERT ... ON DUPLICATE KEY UPDATE
,但我需要更新部分有条件,只有在某些额外条件改变时才执行更新。
然而,对于这个UPDATE
,不允许使用WHERE
语句。是否有任何解决办法?
我无法进行INSERT/UPDATE/SELECT的组合操作,因为这需要在复制过程中工作。
我建议您使用IF()来完成此操作。
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);
这是我们的最终解决方案,非常有效!
插入忽略将确保该行存在于主库和从库中,以防它们曾经分离。
更新...where确保在所有复制完成后,全局只有最新的更新是最终结果。
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();
update test set value = "foo", ts = now() where id = 4 and ts < now()
。 - antakinsert ignore...
,然后是update .... where ts < now()
。 - Andreas Wederbrand您可以使用两个插入语句...因为您可以在源数据的选择部分添加where子句。
选择两组数据,一组将使用“on duplicate”插入,另一组将不使用“on duplicate”插入。
ON DUPLICATE KEY UPDATE
的条件WHERE子句IF()
函数进行条件子句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 )
;
@doupdate
,以标记更新行是否符合条件。然后我们使用相同的变量来处理UPDATE语句中使用的所有数据库列。php_lock
:name
:idString, locked
:bool,
time
:timestamp, locked_by
:stringname
='wwww' AND
locked
=2INSERT 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`);
在重复键
的情况下,不允许我们使用where子句,因此有两种替代方法可以实现相同的效果。
如果您知道大多数时间都会得到重复键,则
a. 使用update查询和where子句首先更新表
b. 如果更新失败,则使用insert查询将记录插入表中
如果您知道大多数时间都要插入到表中,则
a. 使用insert ignore查询将记录插入表中 - 它实际上会忽略插入,如果发现重复键
b. 如果插入忽略失败,则使用update查询更新记录
关于insert ignore
的参考 点击这里
insert ignore
怎么会失败? - Andreas Wederbrandignore
的作用。它会忽略重复的键异常。 - Andreas Wederbrand
ON DUPLICATE KEY UPDATE daily_events.last_event_id = IF(daily_events.last_event_created_at < VALUES(last_event_created_at), VALUES(last_event_id), daily_events.last_event_id);
- boryn