Dit zou eenvoudiger zijn voor UPDATE
, waar extra rijen die zijn toegevoegd aan de update zichtbaar zijn voor de RETURNING
clausule:
- Pre-UPDATE kolomwaarden retourneren met alleen SQL - PostgreSQL-versie
Hetzelfde is momenteel niet mogelijk voor INSERT
. Per documentatie:
De expressie kan elke kolomnaam van de tabel gebruiken met de naam tabelnaam
tabelnaam het doel zijn van de INSERT
commando.
U kunt (data-modificerende) CTE's gebruiken om dit te laten werken.
Ervan uitgaande dat title
om uniek te zijn per zoekopdracht , anders moet je meer doen:
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);
Als title
is niet uniek per zoekopdracht (maar in ieder geval id
is uniek per tafel):
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);
Deze tweede query is gebaseerd op het ongedocumenteerde implementatiedetail dat rijen worden ingevoegd in de opgegeven volgorde. Het werkt in alle huidige versies van Postgres en zal waarschijnlijk niet kapot gaan.
SQL Fiddle.