PostgreSQL 插入冲突错误 - 没有唯一性或排他性约束

6

我在postgres中有两个表,分别是daily_reportsummary_songs

创建这些表的SQL文件在这里:https://nofile.io/f/Ef94rMFRh6C/file.sql

我想要根据以下条件在每天结束时更新summary_songs

  • 如果userid不存在,则需要将daily_report中的记录插入到summary_songs
  • 如果userid存在,则summary_songs.countid = summary_songs.countid + daily_report.countid

我使用以下查询语句来更新summary_songs

insert into summary_songs 
(select * from daily_report as B)
on conflict (userid, songd) 
do update set countid = countid+excluded.countid ;  

我收到以下错误信息:
ERROR: 没有符合ON CONFLICT规范的唯一或排除约束条件。
1个回答

9
要使用on conflict,您需要在summary_songs表上强制执行unique(userid, songd)

SQL Fiddle

PostgreSQL 9.6 Schema Setup:

CREATE TABLE summary_songs (
    date_time date  NOT NULL,
    userid integer NOT NULL,
    songd integer NOT NULL,
    countid integer NOT NULL,
    unique(userid, songd) 
);


CREATE TABLE daily_report(
    date_time date NOT NULL,
    userid integer NOT NULL,
    songd integer NOT NULL,
    countid integer NOT NULL
);


insert into daily_report (date_time, userid, songd, countid) values
(to_date('2017-12-31','YYYY-MM-DD'),  1 ,     1 ,       5),
(to_date('2017-12-31','YYYY-MM-DD'),  2 ,     1 ,      10),
(to_date('2017-12-31','YYYY-MM-DD'),  4 ,     1 ,       7);


insert into summary_songs (date_time, userid, songd, countid) values
(to_date('2017-12-30', 'YYYY-MM-DD'),1, 1,  80),
(to_date('2017-12-30', 'YYYY-MM-DD'),2, 1,  51),
(to_date('2017-12-30', 'YYYY-MM-DD'),3, 1,  66);

查询 1:

select * from daily_report 

结果:

|  date_time | userid | songd | countid |
|------------|--------|-------|---------|
| 2017-12-31 |      1 |     1 |       5 |
| 2017-12-31 |      2 |     1 |      10 |
| 2017-12-31 |      4 |     1 |       7 |

查询2:

select * from summary_songs 

Results:

|  date_time | userid | songd | countid |
|------------|--------|-------|---------|
| 2017-12-30 |      1 |     1 |      80 |
| 2017-12-30 |      2 |     1 |      51 |
| 2017-12-30 |      3 |     1 |      66 |

查询 3:

insert into summary_songs (date_time, userid, songd, countid)
select date_time, userid, songd, countid from daily_report
on conflict (userid, songd) 
do update set 
  countid = summary_songs.countid + excluded.countid ,
  date_time = excluded.date_time

查询4:

select * from summary_songs 

Results:

|  date_time | userid | songd | countid |
|------------|--------|-------|---------|
| 2017-12-30 |      3 |     1 |      66 |
| 2017-12-31 |      1 |     1 |      85 |
| 2017-12-31 |      2 |     1 |      61 |
| 2017-12-31 |      4 |     1 |       7 |

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接