Questo sarebbe più semplice per UPDATE
, dove le righe aggiuntive unite nell'aggiornamento sono visibili a RETURNING
clausola:
- Restituisci i valori delle colonne pre-UPDATE utilizzando solo SQL - Versione PostgreSQL
Lo stesso è attualmente non possibile per INSERT
. Per documentazione:
L'espressione può utilizzare qualsiasi nome di colonna della tabella denominata da nome_tabella
nome_tabella essendo l'obiettivo di INSERT
comando.
Puoi utilizzare CTE (modifica dei dati) per farlo funzionare.
Supponendo title
essere unici per query , altrimenti devi fare di più:
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);
Se title
non è univoco per query (ma almeno id
è unico per tabella):
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);
Questa seconda query si basa sui dettagli di implementazione non documentati che le righe vengono inserite nell'ordine fornito. Funziona in tutte le versioni attuali di Postgres e probabilmente non si romperà.
SQL Fiddle.