使用从其他表上插入返回的 id 更新表

Roc*_*ces 2 sql postgresql common-table-expression sql-update sql-insert

我试图弄清楚如何将 Table1 中的数据插入到 Table2 中,然后使用 Table2 中新创建的 ID 来更新 Table1 中的相应行。

我使用 Postgres 12.4 是为了它的价值

示例:我有两个表,例如usersmetadata

用户表有以下列

| id | info | metadata_id |
Run Code Online (Sandbox Code Playgroud)

元数据表有以下列

| id | data |
Run Code Online (Sandbox Code Playgroud)

我想将表中的所有info值迁移到表的列users中,并使用相应的值更新我的值(当前为空白),本质上是回填外键。datametadatausers.metadata_idmetadata.id

有什么办法可以优雅地完成这个任务吗?我有一个工作查询,它​​锁定两个表并创建一个临时序列以插入到 and 中metadata.idusers.metadata_id但这似乎很脆弱,我需要在元数据表中现有的最高 ID 之后启动序列,这并不理想。

我还尝试使用带有 RETURNING 子句的数据修改 CTE 来更新表users,但无法使其正常工作。

GMB*_*GMB 5

您不能returning在此处使用,因为您需要在插入时跟踪用户和元数据的关联。

我认为首先使用 .CTE 预生成 CTE 中每个用户的元数据序列更简单nextval()。然后,您可以使用该信息插入元数据并更新用户表:

with 
    candidates as (
        select u.*, nextval(pg_get_serial_sequence('metadata', 'id')) new_metadata_id
        from users u
    ),
    inserted as (
        insert into metadata (id, data) overriding system value
        select new_metadata_id, info from candidates
    )
update users u
set metadata_id = c.new_metadata_id
from candidates c
where c.id = u.id   
Run Code Online (Sandbox Code Playgroud)

我们需要语句overriding system value中的子句insert,以便 Postgres 允许我们写入列serial

DB Fiddle 上的演示