【问题标题】:Multiple UPDATE ... FROM same row is not working多个 UPDATE ... FROM 同一行不起作用
【发布时间】:2019-10-13 10:44:53
【问题描述】:

我正在尝试进行多次更新,但它仅适用于第一行。

我的表“用户”有 2 条记录:

create table users
(
  uid        serial                                 not null
    constraint users_pkey
      primary key,
  balance    numeric                  default 0     not null
);


INSERT INTO public.users (uid, balance) VALUES (2, 100);
INSERT INTO public.users (uid, balance) VALUES (1, 100);

我尝试使用查询更新用户“1”两次,但它只更新一次: 用户“1”的余额变为“105”,而不是“115”

update users as u
set balance = balance + c.bal
from (values (1, 5),
             (1, 10)
     ) as c(uid, bal)
where c.uid = u.uid;

为什么它没有更新子查询中的所有行?

【问题讨论】:

    标签: postgresql join sql-update


    【解决方案1】:

    postgresql documentation 没有给出这种行为的原因,但确实指定了它。

    相关引述

    当出现 FROM 子句时,本质上发生的是 目标表连接到 from_list 中提到的表,并且 连接的每个输出行代表一个更新操作 目标表。使用 FROM 时,应确保连接产生 对于要修改的每一行,最多一个输出行。换句话说,一个 目标行不应与另一行连接多于一行 表。如果是这样,那么只有一个连接行将用于 更新目标行,但使用哪一行并不容易 可预测的。

    在执行更新之前使用SELECTGROUP BY 组合行。

    【讨论】:

      【解决方案2】:

      加入前需要在内部查询中进行聚合:

      update users as u
      set balance = balance + d.bal
      from ( 
        select uid, sum(bal) bal
        from ( values (1, 5), (1, 10) ) as c(uid, bal)
        group by uid
      ) d
      where d.uid = u.uid;
      

      Demo on DB Fiddle

      | uid | balance |
      | --- | ------- |
      | 2   | 100     |
      | 1   | 115     |
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-24
        • 2020-02-09
        • 2018-01-07
        • 1970-01-01
        • 2011-06-08
        • 1970-01-01
        • 2016-12-06
        • 1970-01-01
        相关资源
        最近更新 更多