我正在使用Postgresql 9.3.
我想复制一些db记录.由于我正在为表使用自动增量pk id,因此我想从生成的重复记录ID返回到原始ID的id映射.例如,假设我有一个包含2条记录的表格帖子:
[{'id': 1,'title': 'first'},{'id': 2. 'title': 'second'}]
使用sql:
INSERT INTO posts (title) SELECT title FROM posts RETURNING id,??
我希望看到像这样的映射:
[{'id': 3,'from_id': 1},{'id': 4,'from_id': 2}]
关于如何填写上面的问号以使其有效的任何想法?非常感谢!
解决方法
这对于UPDATE来说会更简单,其中加入到更新中的其他行对RETURNING子句是可见的:
> Return pre-UPDATE Column Values Using SQL Only – PostgreSQL Version
INSERT目前无法实现同样的目标. Per documentation:
The expression can use any column names of the table named by table_name
table_name是INSERT命令的目标.
您可以使用(data-modifying) CTEs来实现此功能.
假设每个查询的标题是唯一的,否则你需要做更多:
WITH sel AS ( SELECT id,title FROM posts WHERE id IN (1,2) -- select rows to copy ),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) -- select rows to copy ORDER BY id ),ins AS ( INSERT INTO posts (title) SELECT title FROM sel ORDER BY id -- ORDER redundant to be sure 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,可能不会破坏.