2

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

具体来说,考虑下表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)

但是,该查询似乎不合法。执行时出现语法错误,指出我不能SELECTSET语句中使用。

我也有几个限制:

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

2 回答 2

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))
;

在线示例

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

于 2019-11-29T09:05:45.537 回答
0

尝试这个:

CREATE TABLE Foo(id INT primary key, arr int[]);
INSERT INTO Foo(id, arr) values (1, array[1,2,3]);

INSERT INTO Foo(id, arr) VALUES (1, ARRAY[2,3,4]) 
ON CONFLICT (id) 
DO UPDATE SET arr = (
  with T AS (
    -- Make a table out of existing array value
    SELECT unnest(arr) FROM Foo WHERE id=EXCLUDED.id
  ), S AS (                        
    -- Make a table out of new array    
    SELECT unnest(EXCLUDED.arr)
  ),                                
  -- Union both tables and aggregate back to array
  R AS (
    SELECT array_agg(unnest) AS arr FROM (
      SELECT * FROM T UNION SELECT * FROM S
    ) U
  )
  SELECT arr FROM R
);
于 2019-11-29T08:57:04.000 回答