批量插入,如果在Postgres上发生冲突(批量upsert)则更新

MK *_*ung 33 sql postgresql upsert

我正在编写一个数据挖掘程序,它批量插入用户数据.

当前的SQL只是一个普通的批量插入:

insert into USERS(
    id, username, profile_picture)
select unnest(array['12345']),
    unnest(array['Peter']),
    unnest(array['someURL']),
on conflict (id) do nothing;
Run Code Online (Sandbox Code Playgroud)

如果发生冲突,我该如何更新?我试过了:

...
    unnest(array['Peter']) as a,
    unnest(array['someURL']) as b,
on conflict (id) do 
update set
    username = a,
    profile_picture = b;
Run Code Online (Sandbox Code Playgroud)

但它会引发There is a column named "a" in table "*SELECT*", but it cannot be referenced from this part of the query.错误.

编辑:

USERS非常简单:

create table USERS (
    id      text not null primary key,
    username    text,
    profile_picture text
);
Run Code Online (Sandbox Code Playgroud)

MK *_*ung 73

原来一个特殊的表名为excluded包含要插入的行(虽然名字很奇怪)

insert into USERS(
    id, username, profile_picture)
select unnest(array['12345']),
    unnest(array['Peter']),
    unnest(array['someURL'])
on conflict (id) do 
update set
    username = excluded.username,
    profile_picture = excluded.profile_picture;
Run Code Online (Sandbox Code Playgroud)

http://www.postgresql.org/docs/9.5/static/sql-insert.html#SQL-ON-CONFLICT

ON CONFLICT DO UPDATE中的SET和WHERE子句可以使用表的名称(或别名)访问现有行,并使用特殊排除表访问建议插入的行...

  • 这只是9.5+,作为提醒. (10认同)
  • 那个命名太奇怪了,我真的被排除的部分搞糊涂了。谢谢澄清。 (2认同)