>我正在尝试进行多次更新,但它仅适用于第一行。
我有 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 文档没有给出这种行为的原因,但确实指定了它。
相关报价
当存在 FROM 子句时,本质上发生的是 目标表与from_list中提到的表联接,并且 联接的每个输出行表示 目标表。使用 FROM 时,应确保连接生成 要修改的每一行最多一个输出行。换句话说,一个 目标行不应从另一行联接到多行 表。如果是这样,则只有一个连接行将用于 更新目标行,但不容易使用哪一个 可预言的。
在执行更新之前,使用带有GROUP BY
的SELECT
来合并行。
在加入之前,您需要在内部查询中进行聚合:
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;
DB小提琴上的演示:
| uid | balance |
| --- | ------- |
| 2 | 100 |
| 1 | 115 |