これは、UPDATEの方が簡単です。 、更新に結合された追加の行がRETURNINGに表示されます 条項:
- SQLのみを使用してUPDATE前の列値を返す-PostgreSQLバージョン
同じことは現在ではありません INSERTで可能 。ドキュメントごと:
式では、 table_nameで指定されたテーブルの任意の列名を使用できます。
table_name INSERTのターゲットになる コマンド。
(データ変更)CTEを使用して、これを機能させることができます。
titleを想定 クエリごとに一意である 、それ以外の場合は、さらに多くのことを行う必要があります:
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);
この2番目のクエリは、行が指定された順序で挿入されるという、文書化されていない実装の詳細に依存しています。現在のすべてのバージョンのPostgresで動作し、おそらく壊れることはありません。
SQLフィドル。