我如何更新如果存在,插入,如果没有(AKA“upsert”或“合并”)在MySQL?

有一个简单的方法来INSERT一个行,当它不存在,或UPDATE如果它存在,使用一个MySQL查询?

是的, INSERT ... ON DUPLICATE KEY UPDATE 。 例如:

 INSERT INTO `usage` (`thing_id`, `times_used`, `first_time_used`) VALUES (4815162342, 1, NOW()) ON DUPLICATE KEY UPDATE `times_used` = `times_used` + 1 

我知道这是一个古老的问题,但Google最近在这里引导我,所以我想其他人也来到这里。

@chaos是正确的:存在INSERT ... ON DUPLICATE KEY UPDATE语法。

但是,最初的问题是关于MySQL的具体问题,在MySQL中有REPLACE INTO ...语法。 恕我直言,这个命令更容易,更直接地用于upserts。 从手册:

REPLACE与INSERT完全相同,只是如果表中的旧行与PRIMARY KEY或UNIQUE索引的新行具有相同的值,则在插入新行之前删除旧行。

注意这不是标准的SQL。 手册中的一个例子:

 CREATE TABLE test ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, data VARCHAR(64) DEFAULT NULL, ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id) ); mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00'); Query OK, 1 row affected (0.04 sec) mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42'); Query OK, 2 rows affected (0.04 sec) mysql> SELECT * FROM test; +----+------+---------------------+ | id | data | ts | +----+------+---------------------+ | 1 | New | 2014-08-20 18:47:42 | +----+------+---------------------+ 1 row in set (0.00 sec) 

编辑:只是一个公平的警告, REPLACE INTO不像UPDATE 。 正如手册所说的那样, REPLACE删除行,如果存在的话,插入一个新行。 (注意上面例子中有趣的“2 rows affected”)。也就是说,它将replace现有logging的所有列的值(而不仅仅是更新某些列)。MySQL的REPLACE INTO的行为非常类似于Sqlite的INSERT OR REPLACE INTO 。 如果您只想更新几列(而不是所有列),如果logging已经存在,请参阅此问题的一些解决方法。