对于UPDATE
,这将更加简单,因为添加到更新中的其他行可见于RETURNING
子句中:
但是对于INSERT
目前来说是不可能的。手册:
该表达式可以使用由table_name命名的表的任何列名称
table_name是INSERT
命令的目标。
您可以使用(数据修改) CTEs使其工作。假设title
在查询中是唯一的,否则您需要进行更多操作:
WITH sel AS (
SELECT id, title
FROM posts
WHERE id IN (1,2)
)
, ins AS (
INSERT INTO posts (title)
SELECT title FROM sel
RETURNING id, title
)
SELECT ins.id, sel.id AS from_id
FROM ins
JOIN sel USING (title);
如果每个查询中title
不是唯一的(但至少每个表中id
是唯一的):
WITH sel AS (
SELECT id, title, row_number() OVER (ORDER BY id) AS rn
FROM posts
WHERE id IN (1,2)
ORDER BY id
)
, ins AS (
INSERT INTO posts (title)
SELECT title FROM sel ORDER BY id
RETURNING id
)
SELECT i.id, s.id AS from_id
FROM (SELECT id, row_number() OVER (ORDER BY id) AS rn FROM ins) i
JOIN sel s USING (rn);
这个第二个查询依赖于未记录的实现细节,即按提供的顺序插入行。它适用于所有当前版本的Postgres,并且可能不会出问题。
db<>fiddle 在这里
旧的sqlfiddle
FROM posts oldposts
,然后在RETURNING
子句中引用旧和新的别名。但看起来好像不行。有点棘手。 - Craig Ringer