Sql 如何更新冲突postgres

Sql 如何更新冲突postgres,sql,postgresql,Sql,Postgresql,我有sql语句 create table test ( code varchar, date date, code_2 varchar(2), type varchar(4), sum int default 1 ); alter table test add primary key (code, date, type); insert into test(code, date, code_2, type) select (a

我有sql语句

create table test
(
    code   varchar,
    date   date,
    code_2 varchar(2),
    type   varchar(4),
    sum    int default 1
);

alter table test
    add primary key (code, date, type);

insert into test(code, date, code_2, type)
select (array ['abc', 'xyz'])[ceil(random() * 2)],
       (array ['2021-05-28', '2021-05-27'])[ceil(random() * 2)]::date,
       (array ['qq', 'ee'])[ceil(random() * 2)],
       (array ['ABCD', 'DCBA'])[ceil(random() * 2)]
from generate_series(1, 1000)
on conflict (code, date, type)
    do update set sum = excluded.sum + 1;
我想添加一条记录并对其求和(组码、日期、类型),如果它存在,如果不存在,则添加新记录

但是上面的sql不运行,并且出现错误


错误:发生冲突时,DO UPDATE命令不能再次影响行

错误消息说明了一切。更改
选择
,使其使用相同的键聚合所有行:

INSERT INTO test(code, date, code_2, type, sum)
SELECT (array ['abc', 'xyz'])[ceil(random() * 2)],
       (array ['2021-05-28', '2021-05-27'])[ceil(random() * 2)]::date,
       max((array ['qq', 'ee'])[ceil(random() * 2)]),
       (array ['ABCD', 'DCBA'])[ceil(random() * 2)],
       count(*)
FROM generate_series(1, 1000)
GROUP BY 1, 2, 4
ON CONFLICT (code, date, type)
    DO UPDATE SET sum = test.sum + excluded.sum;

对此,您不需要对冲突进行
。相反,使用CTE生成数据。然后将其聚合以进行插入:

with to_insert as (
       select (array ['abc', 'xyz'])[ceil(random() * 2)] as code,
              (array ['2021-05-28', '2021-05-27'])[ceil(random() * 2)]::date as date,
              (array ['qq', 'ee'])[ceil(random() * 2)] as code_2,
              (array ['ABCD', 'DCBA'])[ceil(random() * 2)] as type
       from generate_series(1, 1000)
      )
insert into test(code, date, code_2, type, sum)
    select code, date, min(code_2), type, count(*)
    from to_insert
    group by code, date, type;
他是一把小提琴

注:

  • 如果表中有现有数据,您仍然可以对冲突使用
    。这个例子不需要它
  • 我怀疑您希望主键中有
    code\u 2
    。上述逻辑仅选择最大值

抱歉@Laurenz Albe,但您可以提供更多细节,我不明白。很抱歉,我添加了一个示例语句。谢谢@Gordon Linoff,我尝试了你的解决方案,它成功了,是的,表是空的