从 select 语句插入时如何使用 postgres Insert ....ON CONFLICT DO UPDATE
How to use postgres Insert ....ON CONFLICT DO UPDATE when inserting from select statement
我有以下 3 个 table。请原谅 table 名称,它们是通用数据库结构命名约定的一部分。
table: tbl_331
id (primary key, integer)
field_3 (text)
table: tbl_329_customid
id (primary key, integer)
fullname (text)
table: tbl_331_to_tbl_329_field
tbl_331_id (integer)
tbl_329_id (integer)
primary key (tbl_331_id, tbl_329_id)
我想编写一个查询,使用匹配值将值插入多对多 table: tbl_331_to_tbl_320_field。如果我使用 DO NOTHING 参数,这有效。
此语句用于插入它发现匹配的值。
insert into schema_1.tbl_331_to_tbl_329_field_3
select X.id, S.id from schema_1.tbl_329 S
JOIN schema_1.tbl_331_customid X on S.field_3=x.fullname
ON CONFLICT DO NOTHING
但我想使用 DO UPDATE,所以如果有冲突,它会更新第二个 ID (S.id)。
例如,如果我将 S.field_3 中的值更改为与新 ID 匹配的某个其他值,我想更新此多对多 table.
中的 ID
insert into schema_1.tbl_331_to_tbl_329_field_3
select X.id, S.id from schema_1.tbl_329 S
JOIN schema_1.tbl_331_customid X on S.field_3=x.fullname
ON CONFLICT ( tbl_331_id, tbl_329_id ) DO UPDATE set S.id = EXCLUDED.id
“这导致列‘id’的错误消息不明确。 “
如果我尝试使用这样的别名:
insert into schema_1.tbl_331_to_tbl_329_field_3
select X.id, S.id as myalias from schema_1.tbl_329 S
JOIN schema_1.tbl_331_customid X on S.field_3=x.fullname
ON CONFLICT ( tbl_331_id, tbl_329_id ) DO UPDATE set S.id = myalias
我得到“myalias 列不存在”
我对 DO UPDATE 的这种语法很陌生。我的假设是,在 ON CONFLICT 之后,您必须指定它会发生冲突的 uniqye/primary 键,然后告诉它要更新什么。
我该如何编写才能更新匹配的新匹配 ID?
insert into schema_1.tbl_331_to_tbl_329_field_3
select X.id, S.id from schema_1.tbl_329 S
JOIN schema_1.tbl_331_customid X on S.field_3=x.fullname
ON CONFLICT ( tbl_331_id, tbl_329_id ) DO UPDATE set S.id = EXCLUDED.id
- 这种类型的
UPDATE
的上下文只是那个名为 EXCLUDED
的特殊 table 本身。您的输入 table 在 UPDATE
中是不可见的,您只能看到您的冲突记录 (EXCLUDED
) 和您试图将它们插入的字段([= 的列15=]).因此,您的 S
无法访问,也没有必要 - 在 ON CONFLICT ... DO UPDATE
中,您正在解决传入数据与目标 table 中已有数据之间的冲突 - Postgres 不介意你从哪里得到它,甚至不试图记住它。
ERROR: column reference "id" is ambiguous
非常不直观。即使您可以随意为输入中的列添加别名——只要它们的顺序和类型与您的目标相匹配——在发生冲突时,它们会被处理,就好像它们已经在目标中一样 table。因此,您的第一个 id
和第二个 id
(或稍后的 myalias
)实际上已经在 EXCLUDED
[=38] 中分别称为 tbl_331_id
和 tbl_329_id
=].您收到错误的原因是因为 Postgres 首先检查歧义 并立即在该点抛出错误,然后再检查这些列是否属于您当前的上下文。
S.id = myalias
没有多大意义,因为它正是 S.id
,您刚刚将其别名为 myalias
.
我有以下 3 个 table。请原谅 table 名称,它们是通用数据库结构命名约定的一部分。
table: tbl_331
id (primary key, integer)
field_3 (text)
table: tbl_329_customid
id (primary key, integer)
fullname (text)
table: tbl_331_to_tbl_329_field
tbl_331_id (integer)
tbl_329_id (integer)
primary key (tbl_331_id, tbl_329_id)
我想编写一个查询,使用匹配值将值插入多对多 table: tbl_331_to_tbl_320_field。如果我使用 DO NOTHING 参数,这有效。
此语句用于插入它发现匹配的值。
insert into schema_1.tbl_331_to_tbl_329_field_3
select X.id, S.id from schema_1.tbl_329 S
JOIN schema_1.tbl_331_customid X on S.field_3=x.fullname
ON CONFLICT DO NOTHING
但我想使用 DO UPDATE,所以如果有冲突,它会更新第二个 ID (S.id)。 例如,如果我将 S.field_3 中的值更改为与新 ID 匹配的某个其他值,我想更新此多对多 table.
中的 ID insert into schema_1.tbl_331_to_tbl_329_field_3
select X.id, S.id from schema_1.tbl_329 S
JOIN schema_1.tbl_331_customid X on S.field_3=x.fullname
ON CONFLICT ( tbl_331_id, tbl_329_id ) DO UPDATE set S.id = EXCLUDED.id
“这导致列‘id’的错误消息不明确。 “
如果我尝试使用这样的别名:
insert into schema_1.tbl_331_to_tbl_329_field_3
select X.id, S.id as myalias from schema_1.tbl_329 S
JOIN schema_1.tbl_331_customid X on S.field_3=x.fullname
ON CONFLICT ( tbl_331_id, tbl_329_id ) DO UPDATE set S.id = myalias
我得到“myalias 列不存在”
我对 DO UPDATE 的这种语法很陌生。我的假设是,在 ON CONFLICT 之后,您必须指定它会发生冲突的 uniqye/primary 键,然后告诉它要更新什么。
我该如何编写才能更新匹配的新匹配 ID?
insert into schema_1.tbl_331_to_tbl_329_field_3
select X.id, S.id from schema_1.tbl_329 S
JOIN schema_1.tbl_331_customid X on S.field_3=x.fullname
ON CONFLICT ( tbl_331_id, tbl_329_id ) DO UPDATE set S.id = EXCLUDED.id
- 这种类型的
UPDATE
的上下文只是那个名为EXCLUDED
的特殊 table 本身。您的输入 table 在UPDATE
中是不可见的,您只能看到您的冲突记录 (EXCLUDED
) 和您试图将它们插入的字段([= 的列15=]).因此,您的S
无法访问,也没有必要 - 在ON CONFLICT ... DO UPDATE
中,您正在解决传入数据与目标 table 中已有数据之间的冲突 - Postgres 不介意你从哪里得到它,甚至不试图记住它。 ERROR: column reference "id" is ambiguous
非常不直观。即使您可以随意为输入中的列添加别名——只要它们的顺序和类型与您的目标相匹配——在发生冲突时,它们会被处理,就好像它们已经在目标中一样 table。因此,您的第一个id
和第二个id
(或稍后的myalias
)实际上已经在EXCLUDED
[=38] 中分别称为tbl_331_id
和tbl_329_id
=].您收到错误的原因是因为 Postgres 首先检查歧义 并立即在该点抛出错误,然后再检查这些列是否属于您当前的上下文。S.id = myalias
没有多大意义,因为它正是S.id
,您刚刚将其别名为myalias
.