mag*_*nus 5 sql postgresql sql-update
考虑以下:
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');
Run Code Online (Sandbox Code Playgroud)
在上面, table 中有一行x我想更新。在 table 中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;
Run Code Online (Sandbox Code Playgroud)
x.t我希望的值为 ,'hiwowthere'但最终的值为'hiwow'。我认为造成这种情况的原因是update语句中的子查询返回两行(首先返回y.t的值),而子句只匹配第一行。'wow'wherey.i = x.i
我可以使用单个update语句实现预期结果吗?如果可以,如何实现?
更新:使用text上述类型仅用于说明目的。我实际上不想修改文本内容,而是使用json_set我在此处发布的函数修改 JSON 内容(How do I edit 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 ;
Run Code Online (Sandbox Code Playgroud)
为了保留顺序,您可能需要额外的包装派生表。SqlFiddle在这里