INSERT ... ON DUPLICATE KEY UPDATE row IF date_added > VALUES(date_added)
INSERT ... ON DUPLICATE KEY UPDATE row IF date_added > VALUES(date_added)
如果满足特定条件,我如何 INSERT
和 ON DUPLICATE KEY
更新整行?
我想更新整个 row
如果 VALUES(date_added)
比 table 旧 date_added
。
我看过这篇文章:
https://thewebfellas.com/blog/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),
last_event_created_at = IF(last_event_created_at < VALUES(last_event_created_at), VALUES(last_event_created_at), last_event_created_at);
但这不是编写语句的灵活方式。
稍后编辑:
首先,因为条件是针对每个将要更新的字段进行评估的,其次,因为您必须注意将更新条件列的行定位在语句的最后位置。否则你会用错误毒化 UPDATE
。
更确切地说,我希望我反转了两个 UPDATE 行的语句也有效:
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_created_at = GREATEST(last_event_created_at, VALUES(last_event_created_at)),
last_event_id = (CASE WHEN last_event_created_at < VALUES(last_event_created_at) THEN VALUES(last_event_id) ELSE last_event_id END);
这是不可能的,因为:
An important thing to keep in mind when using this approach is that the order in which you update your fields is very important. I was wrongly under the impression that the updates took place in one mass-assignment after the entire query had been interpreted by MySQL. But they’re not: the assignments happen in the order they appear in the query.
When the update
is executed with a more recent event, the last_event_created_at
field will be updated, but the last_event_id
field won’t. This is because when the second IF
is evaluated last_event_created_at
has already been updated so that last_event_created_at
is equal to VALUES(last_event_created_at)
. Crazy huh?!
您的查询似乎符合您的要求,所以我没有完全理解您的问题。您可以使用 GREATEST()
:
来简化它
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 = (CASE WHEN last_event_created_at < VALUES(last_event_created_at) THEN VALUES(last_event_id) ELSE last_event_id END),
last_event_created_at = GREATEST(last_event_created_at, VALUES(last_event_created_at));
(使用 CASE
是对等效功能的 ANSI 标准的偏好。)
MySQL 没有提供表达 "update all of these when this condition is met".
的方式
如果满足特定条件,我如何 INSERT
和 ON DUPLICATE KEY
更新整行?
我想更新整个 row
如果 VALUES(date_added)
比 table 旧 date_added
。
我看过这篇文章:
https://thewebfellas.com/blog/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),
last_event_created_at = IF(last_event_created_at < VALUES(last_event_created_at), VALUES(last_event_created_at), last_event_created_at);
但这不是编写语句的灵活方式。
稍后编辑:
首先,因为条件是针对每个将要更新的字段进行评估的,其次,因为您必须注意将更新条件列的行定位在语句的最后位置。否则你会用错误毒化 UPDATE
。
更确切地说,我希望我反转了两个 UPDATE 行的语句也有效:
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_created_at = GREATEST(last_event_created_at, VALUES(last_event_created_at)),
last_event_id = (CASE WHEN last_event_created_at < VALUES(last_event_created_at) THEN VALUES(last_event_id) ELSE last_event_id END);
这是不可能的,因为:
An important thing to keep in mind when using this approach is that the order in which you update your fields is very important. I was wrongly under the impression that the updates took place in one mass-assignment after the entire query had been interpreted by MySQL. But they’re not: the assignments happen in the order they appear in the query.
When the
update
is executed with a more recent event, thelast_event_created_at
field will be updated, but thelast_event_id
field won’t. This is because when the secondIF
is evaluatedlast_event_created_at
has already been updated so thatlast_event_created_at
is equal toVALUES(last_event_created_at)
. Crazy huh?!
您的查询似乎符合您的要求,所以我没有完全理解您的问题。您可以使用 GREATEST()
:
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 = (CASE WHEN last_event_created_at < VALUES(last_event_created_at) THEN VALUES(last_event_id) ELSE last_event_id END),
last_event_created_at = GREATEST(last_event_created_at, VALUES(last_event_created_at));
(使用 CASE
是对等效功能的 ANSI 标准的偏好。)
MySQL 没有提供表达 "update all of these when this condition is met".
的方式