Postgres将数组的每个元素(如果不存在)追加或设置为数组列

Pra*_*sha 6 sql arrays postgresql

如果我有

select arr_str from tabl1;
-> {'a', 'b'}
Run Code Online (Sandbox Code Playgroud)

那么如何将此{'b','c','d'}数组添加到列中arr_str 以便获得以下结果

select arr_str from tabl1;
-> {'a', 'b', 'c', 'd'}
Run Code Online (Sandbox Code Playgroud)

我不想选择列并创建一个新数组进行更新.我只想使用UPDATE查询.

poz*_*ozs 9

我会假设它arr_str是类型的text[](尽管您没有为它们使用正确的格式,所以我可能是错的;如果是这种情况,则需要将您的值转换为text[])。

如果要删除arr_str列中已存在的重复项,请使用以下语句:

update tabl1
set    arr_str = (select array_agg(distinct e) from unnest(arr_str || '{b,c,d}') e)
where  not arr_str @> '{b,c,d}'
Run Code Online (Sandbox Code Playgroud)

或者,当您要保留现有重复项时,请使用以下代码:

update tabl1
set    arr_str = arr_str || array(select unnest('{b,c,d}'::text[]) except select unnest(arr_str))
where  not arr_str @> '{b,c,d}'
Run Code Online (Sandbox Code Playgroud)

这两个语句都不会涉及行,无论如何行都不会受到影响(请看where not arr_str @> '{b,c,d}'谓词)。通常,这是最佳做法,并且在涉及触发器时几乎总是建议这样做。

http://rextester.com/GKS7382


Dmi*_*kin 6

使用默认的pg install,您可以使用||合并两个数组 运营商:

select arr_str || '{a, b}' from tabl1
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,你会得到重复.

为了避免它们,你可以将数组替换为rowset并将其区分开来:

select ARRAY(SELECT DISTINCT UNNEST(arr_str || '{a,b,c}')) from tabl1
Run Code Online (Sandbox Code Playgroud)

如果你的值是整数,那么使用intarray contrib模块和uniq()函数获得uniq数组值有更优雅的方法:https://www.postgresql.org/docs/current/static/intarray.html

您可以使用以下命令添加这些整数数组函数:

CREATE EXTENSION intarray
Run Code Online (Sandbox Code Playgroud)