Dies wäre einfacher für UPDATE
, wobei zusätzliche Zeilen, die in das Update aufgenommen wurden, für RETURNING
sichtbar sind Klausel:
- Spaltenwerte vor dem UPDATE nur mit SQL zurückgeben – PostgreSQL-Version
Das Gleiche gilt derzeit nicht möglich für INSERT
. Per Dokumentation:
Der Ausdruck kann beliebige Spaltennamen der durch table_name benannten Tabelle verwenden
Tabellenname das Ziel von INSERT
ist Befehl.
Sie können (datenmodifizierende) CTEs verwenden, um dies zum Laufen zu bringen.
Angenommen title
eindeutig pro Abfrage sein , sonst müssen Sie mehr tun:
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);
Wenn title
ist nicht pro Abfrage eindeutig (aber mindestens id
ist pro Tabelle eindeutig):
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);
Diese zweite Abfrage stützt sich auf das undokumentierte Implementierungsdetail, dass Zeilen in der angegebenen Reihenfolge eingefügt werden. Es funktioniert in allen aktuellen Versionen von Postgres und wird wahrscheinlich nicht kaputt gehen.
SQL-Geige.