考虑以下几点:
create table tmp.x (i integer, t text);
create table tmp.y (i integer, t text);
delete from tmp.x;
delete from tmp.y;
insert into tmp.x values (1, 'hi');
insert into tmp.y values(1, 'there');
insert into tmp.y values(1, 'wow');
在上面,表 x
中有一行,我想更新它。在表 y
中,有两行,我想将这两行“输入”更新。
下面是我的尝试:
update tmp.x
set t = x.t || y.t
from ( select * from tmp.y order by t desc ) y
where y.i = x.i;
select * from tmp.x;
我希望 x.t
的值是 'hiwowthere'
但最终值是 'hiwow'
。我相信这是因为更新语句中的子查询返回两行(首先返回 'wow'
的 y.t
值),以及 where
子句 y.i = x.i
只匹配第一行。
我能否使用单个 update
语句实现预期的结果,如果可以,如何实现?
更新:上面text
类型的使用仅用于说明目的。我实际上并不想修改文本内容,而是使用我在此处发布的 json_set
函数修改 JSON 内容 (How do I modify fields inside the new PostgreSQL JSON datatype?),尽管我希望该原则可以应用于任何函数,例如作为虚构的 concat_string(column_name, 'string-to-append')
。
更新 2:为了避免在这个问题上浪费时间,我实际上编写了一个小函数来完成它。但是,如果知道这是否可能,以及如何实现,那将是一件好事。
最佳答案
您可以做的是使用 string_agg 建立一个串联的字符串,按 integer i
分组,然后您可以在更新期间加入:
update tmp.x
set t = x.t || y.txt
from (select i, string_agg(t, '') as txt
from(
select tmp.y.i,tmp.y.t
from tmp.y
order by t desc
) z
group by z.i) y
where y.i = x.i ;
为了保持顺序,您可能需要一个额外的包装派生表。 SqlFiddle here
关于sql - PostgreSQL 是否具有在单个查询中多次更新同一行的机制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30296290/