To by bylo jednodušší pro UPDATE
, kde jsou další řádky připojené k aktualizaci viditelné pro RETURNING
klauzule:
- Vrátí hodnoty sloupce před aktualizací pomocí pouze SQL – verze PostgreSQL
Totéž aktuálně ne možné pro INSERT
. Podle dokumentace:
Výraz může používat libovolné názvy sloupců tabulky pojmenované název_tabulky
název_tabulky je cílem INSERT
příkaz.
Aby to fungovalo, můžete použít CTE (upravující data).
Za předpokladu title
být jedinečný na dotaz , jinak musíte udělat více:
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);
Pokud title
není jedinečné na dotaz (ale alespoň id
je jedinečný pro každou tabulku):
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);
Tento druhý dotaz se opírá o nezdokumentované podrobnosti implementace, že řádky jsou vkládány v uvedeném pořadí. Funguje ve všech aktuálních verzích Postgres a pravděpodobně se nerozbije.
SQL Fiddle.