当前位置: 首页 > 知识库问答 >
问题:

如何使用postgres插入...... ON CONFLICT在从选择语句插入时进行更新

颛孙正谊
2023-03-14

我有以下三张桌子。请原谅表名,它们是通用数据库结构命名转换的一部分。

          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)

我想编写一个查询,使用匹配的值将值插入多对多表:tbl_331_to_tbl_320_字段。如果我使用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匹配的其他值,我想更新这个多对多表中的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的这种语法非常陌生。我的假设是,在发生冲突之后,必须指定它将发生冲突的uniqye/主键,然后告诉它要更新什么。

我该如何编写它,以便它将匹配的ID更新为新的匹配ID?

共有1个答案

韩鸿波
2023-03-14
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
  1. 这种类型的UPDATE的上下文只包括名为的特殊表本身。您的输入表在更新中不可见,您只能看到冲突的记录(排除)以及您试图将它们插入的字段(schema_1.tbl_331_to_tbl_329_field_3)。因此,您的S无法访问,也不需要位于冲突的中。。。DO UPDATE您正在解决传入数据与目标表中已有数据之间的冲突——Postgres不介意您从哪里获得数据,甚至不尝试记住
  2. 错误:列引用“id”不明确非常不直观。即使您可以随意在输入中为列添加别名,只要它们的顺序和类型与您的目标相匹配,但在冲突中,它们会像已经在目标表中一样被处理。因此,您的第一个id和第二个id(或以后的myalias)实际上已经在排除的表中分别被称为tbl_331_idtbl_329_id。出现错误的原因是,Postgres首先检查歧义,然后立即在该点抛出错误,然后再检查这些列是否属于当前上下文
  3. S.id=myalias没有多大意义,因为你刚刚把它化名为myalias

 类似资料:
  • 问题内容: 我正在尝试向表中插入其他行,该表要求从另一个表中检索一个值。以下是查询示例: 表的结构为。 我知道以上查询是错误的。有没有办法在插入行时从其他表中检索1个值? 问题答案: 一些DBMS会接受以下内容,并在SELECT语句的周围加上括号:

  • 我试图在postgres表的numeric datatype列中插入一个日期值 在上面的查询中,col1是numeric类型。 我还可以使用value()子句插入一些值,使用select语句插入一些值吗?例如: 在上表中:1。col1即将到来序列2。col2和col3来自两个表的连接,即表B和表C 3。col4和col5是硬编码值 如何在一个查询中实现这一点? 通过两个表的连接进行插入,可按如下方

  • 问题内容: 昨天我问了这个问题:如果在mysql中插入语句并且答案很好用。问题是,如果值不存在,我需要在表中插入一行。FE 我能怎么做?在互联网上我找不到答案:( 问题答案: 我假设您的表名为tbl。 纯粹是为了方便那些要求所有SELECT语句都应该包含FROM以及可能包含其他子句的人们。MySQL可能会忽略这些子句。如果没有引用表,MySQL不需要FROM DUAL。 如其他提到的那样,如果您的

  • 我在后文10中有如下陈述: 但是,由于我插入了多个值,除了这个值之外,我还有什么选择:

  • 问题内容: 好的。简而言之,我正在尝试执行INSERT SELECT,例如: 当然,@key不会从每个插入中返回每个后续的LAST_INSERT_ID(),而是仅从最后一个插入返回ID。 基本上,我将旧的USER表拆分为ENTITY和USER,例如: 我为什么要这样做?基本上,我有一个“商店”实体,它将具有“用户”公用的字段,例如地址和电话号码。因此,任何“ ENTITY”都可能没有多个地址(送货

  • 问题内容: 我有一个产品对象,它属于某些类别,即经典的多对一关系。 我想插入和更新产品而不预先选择类别。像这样: 要么 是否可以在不选择类别的情况下进行更新和插入?我不想为此使用HQL或直接查询。 问题答案: session.load()专门用于此类情况。以下: 不会打数据库。但是,如果没有提供给定ID的类别,它将在稍后阶段(刷新期间或多或少)引发异常。 使用速度快且没有副作用(级联等)。