使用唯一键更新多行

时间:2013-01-02 17:14:11

标签: mysql database python-db-api

我想更新由唯一键标识的多行而不插入新行。

以下是我的表格:

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

2 个答案:

答案 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个查询将不会满足条件。