これは、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フィドル。