sql >> Databasteknik >  >> RDS >> PostgreSQL

INSERT INTO ... FRÅN SELECT ... RETURNERAR ID-mappningar

Detta skulle vara enklare för UPDATE , där ytterligare rader kopplade till uppdateringen är synliga för RETURNING klausul:

  • Återställ kolumnvärden före UPPDATERING med endast SQL - PostgreSQL-version

Detsamma är för närvarande inte möjligt för INSERT . Per dokumentation:

Uttrycket kan använda alla kolumnnamn i tabellen som heter tabellnamn

tabellnamn är målet för INSERT kommando.

Du kan använda (datamodifierande) CTE:er för att få detta att fungera.
Förutsatt title vara unik per fråga , annars måste du göra mer:

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);

Om title är inte unik per fråga (men åtminstone id är unik per tabell):

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);

Den här andra frågan bygger på den odokumenterade implementeringsdetaljen att rader infogas i den angivna ordningen. Det fungerar i alla nuvarande versioner av Postgres och kommer förmodligen inte att gå sönder.

SQL-fiol.



  1. SQL Server Oanvänd Index

  2. Hur TRIM()-funktionen fungerar i MySQL

  3. Lägga till fler avancerade funktioner som att hantera kategorier och rösta på trådar och inlägg

  4. PL/SQL ORA-01422:exakt hämtning returnerar fler än begärt antal rader