Това би било по-лесно за UPDATE
, където допълнителните редове, обединени в актуализацията, са видими за RETURNING
клауза:
- Връщане на стойности на колони преди АКТУАЛИЗАЦИЯ, използвайки само SQL – версия на PostgreSQL
Същото в момента не възможно за INSERT
. По документация:
Изразът може да използва всякакви имена на колони на таблицата, наречена от име_на_таблица
име_на_таблица като целта на 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);
Тази втора заявка разчита на недокументираните детайли за изпълнение, че редовете се вмъкват в предоставения ред. Работи във всички текущи версии на Postgres и вероятно няма да се счупи.
SQL Fiddle.