sql >> Databáze >  >> RDS >> PostgreSQL

INSERT INTO ... FROM SELECT ... VRACENÍ id mapování

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.



  1. Uživatelská oprávnění MySQL

  2. Skupiny konverzace SQL Server Service Broker

  3. Chyba SQL ORA-01722:neplatné číslo

  4. Proveďte více dotazů v jediném příkazu Oracle v C#