为什么如果在UPDATE查询中使用jsonb_set
作为新值,它只更新结果集的第一行?
请在此处查看此示例:http://sqlfiddle.com/#!17/0bdd8/5
同一帖子的回复中有两个条目,但是当我尝试分配一个键入用户名的随机值时,它只会将其插入第一个值而不是第二个值:
UPDATE posts
SET a_to_b = jsonb_set(posts.a_to_b, array[username::text], to_jsonb(random()))
FROM reactions
WHERE posts.id = reactions.post_id;
答案 0 :(得分:2)
FROM子句中有多行要修改单行。 The documentation清楚地解释了这一点:
使用FROM时,应确保连接为每个要修改的行生成最多一个输出行。换句话说,目标行不应该连接到其他表的多个行。如果是,那么只有一个连接行将用于更新目标行,但是将使用哪一个不容易预测。
您可以通过聚合子查询中的预期值来执行单个更新。使用聚合函数jsonb_object_agg()
:
update posts p
set a_to_b = agg
from (
select p.id, jsonb_object_agg(username, random()) as agg
from posts p
join reactions r on p.id = r.post_id
group by p.id
) s
where s.id = p.id;
或者,您可以使用anonymous code block重复更新单行,例如:
do $$
declare rec record;
begin
for rec in
select *
from posts p
join reactions r on p.id = r.post_id
loop
update posts
set a_to_b = jsonb_set(a_to_b, array[rec.username], to_jsonb(random()))
where posts.id = rec.post_id;
end loop;
end $$;
第二种解决方案可能不是最理想的,特别是对于大量的聚合值。