85

ばかげているが単純な例:受け取ったアイテムの合計を保持するテーブル「Item」があると仮定します。

Item_Name              Items_In_Stock

ここではアイテム名が主キーです。アイテムAを数量Xで受け取ったときに、次のことを達成する方法。

アイテムが存在しない場合は、アイテムAの新しいリコアを挿入し、在庫のあるアイテムをXに設定します。在庫のあるアイテムがYであるレコードが存在する場合、在庫のあるアイテムの新しい値は(X + Y)です。

INSERT INTO `item`
(`item_name`, items_in_stock)
VALUES( 'A', 27)
ON DUPLICATE KEY UPDATE
`new_items_count` = 27 + (SELECT items_in_stock where item_name = 'A' )

私の問題は、実際のテーブルに複数の列があることです。更新部分に複数のselectステートメントを記述するのは良い考えですか?

もちろん、コードでそれを行うことはできますが、より良い方法はありますか?

4

6 に答える 6

163

私のコメントで述べたように、ON DUPLICATE KEY が発生する原因となっている行を参照するために副選択を行う必要はありません。したがって、あなたの例では、次を使用できます。

INSERT INTO `item`
(`item_name`, items_in_stock)
VALUES( 'A', 27)
ON DUPLICATE KEY UPDATE
`new_items_count` = `new_items_count` + 27

ほとんどのことは本当に単純であることを忘れないでください。単純であるべきことを複雑にしすぎていることに気付いた場合は、間違った方法でやっている可能性が高いです:)

于 2011-05-24T09:39:32.587 に答える
13

この例からアイデアを得ることができます:

ユーザーごとの 7 日間のデータを追加するとします。

userid と day のように一意の値を持つ必要があります

UNIQUE KEY `seven_day` (`userid`,`day`)

ここにテーブルがあります

CREATE TABLE `table_name` (
  `userid` char(4) NOT NULL,
  `day` char(3) NOT NULL,
  `open` char(5) NOT NULL,
  `close` char(5) NOT NULL,
  UNIQUE KEY `seven_day` (`userid`,`day`)
);

そして、あなたのクエリは

INSERT INTO table_name (userid,day,open,close) 
    VALUES ('val1', 'val2','val3','val4') 
        ON DUPLICATE KEY UPDATE open='val3', close='val4';

例:

<?php
//If your data is
$data= array(
        'sat'=>array("userid"=>"1001", "open"=>"01.01", "close"=>"11.01"),
        'sun'=>array("userid"=>"1001", "open"=>"02.01", "close"=>"22.01"),
        'sat'=>array("userid"=>"1001", "open"=>"03.01", "close"=>"33.01"),
        'mon'=>array("userid"=>"1002", "open"=>"08.01", "close"=>"08.01"),
        'mon'=>array("userid"=>"1002", "open"=>"07.01", "close"=>"07.01")
    );


//If you query this in a loop
//$conn = mysql_connect("localhost","root","");
//mysql_select_db("test", $conn);

foreach($data as $day=>$info) {
    $sql = "INSERT INTO table_name (userid,day,open,close) 
                VALUES ('$info[userid]', '$day','$info[open]','$info[close]') 
            ON DUPLICATE KEY UPDATE open='$info[open]', close='$info[close]'";
    mysql_query($sql);
}
?>

あなたのデータはテーブルにあります:

+--------+-----+-------+-------+
| userid | day | open  | close |
+--------+-----+-------+-------+
| 1001   | sat | 03.01 | 33.01 |
| 1001   | sun | 02.01 | 22.01 |
| 1002   | mon | 07.01 | 07.01 |
+--------+-----+-------+-------+
于 2013-09-06T07:07:45.360 に答える
1

これはアップサートの構文です

INSERT INTO `{TABLE}` (`{PKCOLUMN}`, `{COLUMN}`) VALUES (:value)
ON DUPLICATE KEY UPDATE `{COLUMN}` = :value_dup';
于 2013-11-16T21:34:12.507 に答える