使用mysql在单个查询中更新多条记录

Posted

技术标签:

【中文标题】使用mysql在单个查询中更新多条记录【英文标题】:Update multiple records in single query using mysql 【发布时间】:2020-10-21 08:14:30 【问题描述】:

我的 mysql 数据库中有两个表:

用户表:

  id   |   name   |   balance   
---------------------------------
     5    |   john    |     10000
     7    |   mike    |     12000
     8    |   jane    |     5680

存款表:

   id   |   name  |   userId  | amount
-------------------------------------------
     1    |   D1    |     5       | 500
     2    |   D2    |     7       | 1000
     3    |   D2    |     8       | 1500

现在,我有存款 ID,即 1、2、3。我必须用相应的存款更新用户表。

update users set balance = balance + (select amount from deposit where id = 1) where Id = (select userid from deposit where id = 1);
update users set balance = balance + (select amount from deposit where id = 2) where Id = (select userid from deposit where id = 2);
update users set balance = balance + (select amount from deposit where id = 3) where Id = (select userid from deposit where id = 3);

上面的代码有效。但是,如果我们有像 1、2、3 这样的存款 ID,我们可以在一个查询中进行上述查询吗?可以使用 IN 运算符。请提出您的见解。谢谢。

【问题讨论】:

【参考方案1】:

您必须在UPDATE 语句中加入表:

update users u
inner join deposit d on d.userid = u.id
set u.balance = u.balance + d.amount
where d.id in (1, 2, 3)

请参阅demo。 结果:

> id | name | balance
> -: | :--- | ------:
>  5 | john |   10500
>  7 | mike |   13000
>  8 | jane |    7180

【讨论】:

【参考方案2】:

多表更新应该看到https://dev.mysql.com/doc/refman/8.0/en/update.html

update users join deposit on users.id = deposit.userid
set balance = balance + amount;

我不清楚你为什么限制为 1,2,3 所以我把它省略了,你可以在必要时添加一个 where 条件。如果您想跟踪更新给用户的最后一次存款,我建议您向用户添加一列以记录它。

【讨论】:

【参考方案3】:

使用用户 ID 连接用户和存款表将满足您的需求。这样,它会根据连接条件自动从存款表中选择要使用的值:

UPDATE 
  users u 
INNER JOIN deposit d 
  ON d.userid = u.id 
SET 
  balance = u.balance + d.amount 
WHERE 
  d.id IN (1,2,3);

工作演示:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=dad9b716fa0bf441ca9ed4f13df562a3

【讨论】:

【参考方案4】:

如果你想安全,你应该使用:

update users u join
       (select userid, sum(amount) as amount
        from deposit d
        group by userid
       ) d
       on u.id = d.userid
    set balance = balance + d.amount;

如果deposit 表可以有来自同一用户的多个存款,则提前聚合非常重要。尽管示例数据没有这样的示例,但您的问题并未表明这是不可能的。

请注意,您的代码在deposit 表中逐个编号,因此不存在此问题。您也可以将其替换为相关子查询:

update users u
    set balance = balance + (select sum(amount)
                             from deposit d
                             where d.userid = u.id
                            ) 
    where exists (select 1
                  from deposit d
                  where d.userid = u.id
                 ) ;

【讨论】:

以上是关于使用mysql在单个查询中更新多条记录的主要内容,如果未能解决你的问题,请参考以下文章

mysql进阶 十四 批量更新与批量更新多条记录的不同值实现方法

mysql 批量更新与批量更新多条记录的不同值实现方法

Mysql Query Group Concat 限制单个查询中子表的多条记录

MySql中使用INSERT INTO语句更新多条数据的例子

如果 mysql 数据库中的表中不存在,则更新或插入多条记录

求助一条mysql 更新 语句 where 后面为查询的结果