I have sql statement
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;
I want to add a record and sum it on (a group code, date, type) if it exist, if it's not, add new record
but above sql do not run and the error
ERROR: ON CONFLICT DO UPDATE command cannot affect row a second time
The error message says it all. Change the SELECT
so that it aggregates all rows with the same key:
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;
You don't need on conflict
for this. Instead, generate the data using a CTE. Then aggregate it for insert:
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;
Here is a db<>fiddle.
Notes:
on conflict
if the table has existing data. It is just not needed for this example.code_2
in the primary key. The above logic just chooses the maximum value.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.