如何执行UPSERT,以便我可以在更新部分中使用新值和旧值

愚蠢但简单的例子:假设我有一个表“项目”,我保存收到的项目的总计。

Item_Name Items_In_Stock 

项目名称是主键。 当我收到数量为X的物品A时,如何达到以下要求。

如果项目不存在,则为项目A插入一个新的logging,并将库存项目设置为X,如果存在库存项目为Y的logging,则库存项目中的新值为(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语句是一个好主意吗?

当然,我可以在代码中做到这一点,但有没有更好的办法?

正如我的评论中所提到的,您不必执行子select来引用导致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 

请记住,大多数事情是非常简单的,如果你赶上你自己过于简单的事情,那么你很可能做错了方式:)

你可以从这个例子中得到一些想法:

假设你想添加用户明智的七天数据

它应该具有独特的userid和一天的价值

 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 | +--------+-----+-------+-------+ 

虽然迈克尔的答案是正确的,但你需要更多地了解一下以编程方式进行upsert:

首先,创build你的表,并指定你想要一个唯一索引的列:

 CREATE TABLE IF NOT EXISTS Cell ( cellId BIGINT UNSIGNED, attributeId BIGINT UNSIGNED, entityRowId BIGINT UNSIGNED, value DECIMAL(25,5), UNIQUE KEY `id_ce` (`cellId`,`entityRowId`) ) 

然后插入一些值:

 INSERT INTO Cell VALUES( 1, 6, 199, 1.0 ); 

尝试再次做同样的事情,你会得到一个重复的关键错误,因为cellIdentityRowId是相同的:

 INSERT INTO Cell VALUES( 1, 6, 199, 1.0 ); 

关键字'id_ce'重复input'1-199'

这就是为什么我们使用upsert命令:

 INSERT INTO Cell ( cellId, attributeId, entityRowId, value, s, l, p, t ) VALUES( 1, 6, 199, 300.0 ) ON DUPLICATE KEY UPDATE `value` = `value` + VALUES(`value`) 

该命令将已经存在的值1.0作为值,并执行value = value + 300.0

所以即使执行上面的命令后,表中只会有一行,其值为302.0

这是一个upsert的语法

 INSERT INTO `{TABLE}` (`{PKCOLUMN}`, `{COLUMN}`) VALUES (:value) ON DUPLICATE KEY UPDATE `{COLUMN}` = :value_dup';