mysql不同字段批量更新_mysql批量更新多条记录的同一字段为不同值

mysql更新数据的某个字段,一般这样写:

UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value';

也可以这样用in指定要更新的记录:

UPDATE mytable SET myfield = 'value' WHERE other_field in ('other_values');

这里注意 ‘other_values’ 是一个逗号(,)分隔的字符串,如:1,2,3

如果更新多条数据而且每条记录要更新的值不同,可能很多人会这样写:

foreach ($values as $id => $myvalue) {

$sql = "UPDATE mytable SET myfield = $myvalue WHERE id = $id";

mysql_query($sql);

}

即是循环一条一条的更新记录。一条记录update一次,这样性能很差,也很容易造成阻塞。

那么能不能一条sql语句实现批量更新呢?mysql并没有提供直接的方法来实现批量更新,但是可以用点小技巧来实现。

UPDATE mytable

SET myfield = CASE id

WHEN 1 THEN 'myvalue1'

WHEN 2 THEN 'myvalue2'

WHEN 3 THEN 'myvalue3'

END

WHERE other_field ('other_values')

如果where条件查询出记录的id不在CASE范围内,myfield将被设置为空。

如果更新多个值的话,只需要稍加修改:

UPDATE mytable

SET myfield1 = CASE id

WHEN 1 THEN 'myvalue11'

WHEN 2 THEN 'myvalue12'

WHEN 3 THEN 'myvalue13'

END,

myfield2 = CASE id

WHEN 1 THEN 'myvalue21'

WHEN 2 THEN 'myvalue22'

WHEN 3 THEN 'myvalue23'

END

WHERE id IN (1,2,3)

这里以php为例,构造这两条mysql语句:

更新多条单个字段为不同值, mysql模式

$ids_values = array(

1 => 11,

2 => 22,

3 => 33,

4 => 44,

5 => 55,

6 => 66,

7 => 77,

8 => 88,

);

$ids = implode(',', array_keys($ids_values ));

$sql = "UPDATE mytable SET myfield = CASE id ";

foreach ($ids_values as $id=> $myvalue) {

$sql .= sprintf("WHEN %d THEN %d ", $id, $myvalue);

}

$sql .= "END WHERE id IN ($ids)";

echo $sql.";
";

输出:

UPDATE mytable SET myfield = CASE id WHEN 1 THEN 11 WHEN 2 THEN 22 WHEN 3 THEN 33 WHEN 4 THEN 44 WHEN 5 THEN 55 WHEN 6 THEN 66 WHEN 7 THEN 77 WHEN 8 THEN 88 END WHERE id IN (1,2,3,4,5,6,7,8);

更新多个字段为不同值, PDO模式

$data = array(array('id' => 1, 'myfield1val' => 11, 'myfield2val' => 111), array('id' => 2, 'myfield1val' => 22, 'myfield2val' => 222));

$where_in_ids = implode(',', array_map(function($v) {return ":id_" . $v['id'];}, $data));

$update_sql = 'UPDATE mytable SET';

$params = array();

$update_sql .= ' myfield1 = CASE id';

foreach($data as $key => $item) {

$update_sql .= " WHEN :id_" . $key . " THEN :myfield1val_" . $key . " ";

$params[":id_" . $key] = $item['id'];

$params[":myfield1val_" . $key] = $item['myfield1val'];

}

$update_sql .= " END";

$update_sql .= ',myfield2 = CASE id';

foreach($data as $key => $item) {

$update_sql .= " WHEN :id_" . $key . " THEN :myfield2val_" . $key . " ";

$params[":id_" . $key] = $item['id'];

$params[":myfield1va2_" . $key] = $item['myfield2val'];

}

$update_sql .= " END";

$update_sql .= " WHERE id IN (" . $where_in_ids . ")";

echo $update_sql.";
";

var_dump($params);

输出:

UPDATE mytable SET myfield1 = CASE id WHEN :id_0 THEN :myfield1val_0 WHEN :id_1 THEN :myfield1val_1 END,myfield2 = CASE id WHEN :id_0 THEN :myfield2val_0 WHEN :id_1 THEN :myfield2val_1 END WHERE id IN (:id_1,:id_2);

array (size=6)

':id_0' => int 1

':myfield1val_0' => int 11

':id_1' => int 2

':myfield1val_1' => int 22

':myfield1va2_0' => int 111

':myfield1va2_1' => int 222

另外三种批量更新方式

1. replace into 批量更新

replace into mytable(id, myfield) values (1,'value1'),(2,'value2'),(3,'value3');

2. insert into ...on duplicate key update批量更新

insert into mytable(id, myfield1, myfield2) values (1,'value11','value21'),(2,'value12','value22'),(3,'value13','value23') on duplicate key update myfield1=values(myfield2),values(myfield2)+values(id);

3. 临时表

DROP TABLE IF EXISTS `tmptable`;

create temporary table tmptable(id int(4) primary key,myfield varchar(50));

insert into tmptable values (1,'value1'),(2,'value2'),(3,'value3');

update mytable, tmptable set mytable.myfield = tmptable.myfield where mytable.id = tmptable.id;

【replace into】和【insert into】更新都 依赖于主键或唯一值 ,并都可能造成新增记录的操作的 结构隐患

【replace into】操作本质是对重复记录先delete然后insert,如果 更新的字段不全缺失的字段将被设置成缺省值

【insert into】则只是update重复的记录,更改的字段只能依循公式值

【临时表】方式需要用户有 temporary 表的create 权限

数量较少时【replace into】和【insert into】性能最好,数量大时【临时表】最好,【CASE】则具有通用型也不具结构隐患

(责任编辑:最模板)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值