Dette ville være lettere for UPDATE
, hvor yderligere rækker, der er knyttet til opdateringen, er synlige for RETURNING
klausul:
- Returnér præ-OPDATERING kolonneværdier kun ved brug af SQL - PostgreSQL-version
Det samme er i øjeblikket ikke muligt for INSERT
. Per dokumentation:
Udtrykket kan bruge alle kolonnenavne i tabellen navngivet af tabelnavn
tabelnavn er målet for INSERT
kommando.
Du kan bruge (data-modificerende) CTE'er til at få dette til at fungere.
Under forudsætning af title
at være unik pr. forespørgsel , ellers skal du gøre mere:
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);
Hvis title
er ikke unik pr. forespørgsel (men i det mindste id
er unik pr. tabel):
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);
Denne anden forespørgsel er afhængig af de udokumenterede implementeringsdetaljer, som rækker er indsat i den angivne rækkefølge. Det virker i alle nuværende versioner af Postgres og går sandsynligvis ikke i stykker.
SQL Fiddle.