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

Bulk insert, update if on conflict (bulk upsert) on Postgres

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

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

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

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

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

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

编辑:

USERS

Table很简单:

create table USERS (
    id      text not null primary key,
    username    text,
    profile_picture text
);

原来一个名为 excluded 的特殊 table 包含 row-to-be-inserted (虽然名字很奇怪)

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;

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

The SET and WHERE clauses in ON CONFLICT DO UPDATE have access to the existing row using the table's name (or an alias), and to rows proposed for insertion using the special excluded table...

对于从另一个 table 批量插入,如果它们相同,您可以这样做:

INSERT INTO table_a (SELECT * FROM table_b)
ON CONFLICT ON CONSTRAINT "pk_guid"
DO UPDATE SET
column1 = excluded.column1, 
column2 = excluded.column2,
column3 = excluded.column3,
......  ;