我想更新由唯一键标识的多行而不插入新行。
以下是我的表格:
CREATE TABLE `insert_update_ignore` (
`obj_id` int(11) NOT NULL,
`obj_type` tinyint(4) NOT NULL,
`value` int(11) DEFAULT '-1',
UNIQUE KEY `unique_key` (`obj_id`,`obj_type`))
ENGINE=InnoDB DEFAULT CHARSET=utf8
该表有一些现有记录:
mysql> select * from insert_update_ignore;
+--------+----------+-------+
| obj_id | obj_type | value |
+--------+----------+-------+
| 1 | 1 | -1 |
| 1 | 2 | -1 |
| 2 | 1 | -1 |
| 2 | 2 | -1 |
+--------+----------+-------+
我有一些值来更新表格中的value
列。
INSERT INTO insert_update_ignore(obj_id, obj_type, value)
VALUES(1, 1, 1),
(1, 2, 3),
(2, 1, 1),
(2, 2, 5),
(3, 1, 10)
ON DUPLICATE KEY UPDATE
value = VALUES(value);
这几乎完成了这项工作,只是将最后一个值,即(3,1,10)插入表中。不应插入此项,因为之前不存在唯一键(3,1)。
我如何才能完成UPDATE
部分,而不是INSERT
?如果,表格架构可以更改
存在更好的实施。要更新的值是从其他数据库计算的(在不同的机器和不同的端口上运行)。
我挖出下面的那个做的工作,但是如果数值是千,那么声明太大了。有更优雅的方法吗?谢谢,如果有人可以帮助解决这个问题。 P.S我用Python编写它并使用MySQLdb库。
UPDATE insert_update_ignore
SET value = CASE
WHEN (obj_id = 1 AND obj_type = 1) THEN 1
WHEN (obj_id = 1 AND obj_type = 2) THEN 3
WHEN (obj_id = 2 AND obj_type = 1) THEN 1
WHEN (obj_id = 2 AND obj_type = 2) THEN 5
WHEN (obj_id = 3 AND obj_type = 1) THEN 10
ELSE value
END
WHERE (obj_id, obj_type) IN ((1, 1), (1,2), (2, 1), (2, 2), (3, 1));
答案 0 :(得分:1)
您可以先将要更新的所有值放入临时表中。 然后,如果可以连接原始表中的所有值,则从临时表中更新它们。
create temporary table temp like insert_update_ignore;
insert into temp
values(1, 1, 1),
(1, 2, 3),
(2, 1, 1),
(2, 2, 5),
(3, 1, 10);
update insert_update_ignore i
join temp t
using (obj_id, obj_type)
set i.value = t.value;
drop temporary table temp;
我已将所有这些都放入SQLFiddle。
答案 1 :(得分:0)
INSERT
的全部目的是插入新行,因此当然会插入一个新行(如果找不到重复的键;否则,请更新它)。如果您只想更新现有行,请使用UPDATE
个查询。
而不是使用CASE ... WHEN ... THEN ... ELSE ... END
迭代每个唯一键和UPDATE ... WHERE ...
。
修改强>
例如:
UPDATE `insert_update_ignore` SET `value` = 1 WHERE `obj_id` = 1 AND `obj_type` = 1;
UPDATE `insert_update_ignore` SET `value` = 3 WHERE `obj_id` = 1 AND `obj_type` = 2;
UPDATE `insert_update_ignore` SET `value` = 1 WHERE `obj_id` = 2 AND `obj_type` = 1;
UPDATE `insert_update_ignore` SET `value` = 5 WHERE `obj_id` = 2 AND `obj_type` = 2;
UPDATE `insert_update_ignore` SET `value` = 10 WHERE `obj_id` = 3 AND `obj_type` = 1;
前4个查询将更新符合WHERE
子句中条件的行,而最后4个查询将不会满足条件。