PostgreSQL-将数组的值更新为其元素与另一个数组的元素的唯一并集

时间:2019-11-28 19:25:41

标签: sql arrays postgresql

我遇到了一个问题,用另一个数组中不存在的值更新数组的元素。

具体来说,请考虑下表tbl1

+-----------------------------------+
|   c1  |   c2  |   c3  |   c4      |
+-----------------------------------+
|   A   |   B   |   C   | [1, 2, 3] |
|-----------------------------------|

假设我要用以下数据更新列c4[2, 3, 4]。 我希望c4的更新值为[1, 2, 3, 4]

到目前为止,我尝试了以下操作:

INSERT INTO 
    tbl1 (
        c1, c2, c3, c4
    ) 
VALUES ....
ON CONFLICT (c1, c2) DO UPDATE
SET c3=EXCLUDED.c3,
    c4=(SELECT ARRAY_AGG(x ORDER BY x) FROM (SELECT DISTINCT UNNEST(ARRAY_CAT(c4, EXCLUDED.c4)) AS x) AS s)

但是,查询似乎不合法。 我在执行它时遇到语法错误,指出我不能在SELECT语句中使用SET

我也有几个限制:

  1. 我必须更新值on conflict
  2. 我无法在数据库中创建辅助函数
  3. 它必须是单个查询

2 个答案:

答案 0 :(得分:0)

尝试一下:

Clock

答案 1 :(得分:0)

这对我有用:

insert into the_table (c1,c2,c3,c4)
values ('A', 'B', 'new', array[2,3,4])
on conflict (c1,c2)
 do update set 
     c3 = excluded.c3, 
     c4 = (select array_agg(distinct x order by x) 
           from unnest(the_table.c4||excluded.c4) as t(x))
;

Online example

INSERT部分中的null值使原始数组保持不变,因为array[1,2,3]||null::int[]产生{1,2,3}。如果您不希望这样做,则可能需要在更新部分添加一些CASE表达式。