0

新しい行を挿入せずに、一意のキーで識別される複数の行を更新したい。

以下は私のテーブルです:

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か? より適切な実装が存在する場合は、テーブル スキーマを変更できます。更新される値は、他のデータベース (別のマシンおよび別のポートで実行されている) から計算されます。

以下のものを掘り出して仕事をしますが、値が数千の場合、ステートメントは大きすぎます。これを行うためのよりエレガントな方法はありますか? 誰かがこれについて助けることができればありがとう。PSこれを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));
4

2 に答える 2

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に入れました。

于 2013-01-02T18:31:49.857 に答える
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;

WHERE最初の 4 つのクエリは、句の条件に一致する行を更新しますが、最後のクエリは、条件を満たす行がないため更新しません。

于 2013-01-02T17:18:58.610 に答える