如果我有一张桌子A
,像这样:
A {
id SERIAL
title TEXT
...
parentId INT references A.id via a foreign key constraint
}
我正在从A_SOURCE
没有parentId
列的源表中提取数据。取而代之的是一parentTitle
列。所以源表看起来像这样:
A_SOURCE {
title TEXT
parentTitle TEXT
}
在我意识到我无法轻松地将源中的列解析为目标中的列之前,我开始编写一个 upsert 语句以A
通过从表中选择插入到表中。A_SOURCE
parentTitle
parentId
由于我无法确定在处理子项时是否已插入父项,因此连接或子查询可能不会返回任何结果。
我的 upsert 声明看起来像这样:
with source as (
select
title
parentTitle
from A_SOURCE
)
insert into A
select
title
... I don't think I can resolve to parentId here?
from source
on concflict ...;
我知道我可以运行两个单独的语句:
- 插入
null
作为 parentId - 然后更新第二条语句中的 parentId 字段
但是可以在单个查询中执行此操作吗?
使用递归 CTE 准备要插入的值,该 CTE 预先计算
id
s 并定义顺序。然后按顺序插入:该解决方案的美妙之处在于它使用了后面的序列
a.id
(a_id_seq
在示例中),因此在我们完成后序列自动具有正确的值。该解决方案假定数据
a_source
正确,即不包含循环。