sql >> Database teknologi >  >> RDS >> PostgreSQL

INSERT INTO ... FRA SELECT ... RETURNERER id-tilknytninger

Dette ville være lettere for UPDATE , hvor yderligere rækker, der er knyttet til opdateringen, er synlige for RETURNING klausul:

  • Returnér præ-OPDATERING kolonneværdier kun ved brug af SQL - PostgreSQL-version

Det samme er i øjeblikket ikke muligt for INSERT . Per dokumentation:

Udtrykket kan bruge alle kolonnenavne i tabellen navngivet af tabelnavn

tabelnavn er målet for INSERT kommando.

Du kan bruge (data-modificerende) CTE'er til at få dette til at fungere.
Under forudsætning af title at være unik pr. forespørgsel , ellers skal du gøre mere:

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

Hvis title er ikke unik pr. forespørgsel (men i det mindste id er unik pr. tabel):

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

Denne anden forespørgsel er afhængig af de udokumenterede implementeringsdetaljer, som rækker er indsat i den angivne rækkefølge. Det virker i alle nuværende versioner af Postgres og går sandsynligvis ikke i stykker.

SQL Fiddle.



  1. Sådan slipper du udenlandske nøglebegrænsninger i SQL Server-databasen for alle tabellerne - SQL Server / TSQL vejledning del 72

  2. Konfigurer Master-Master MySQL-databasereplikering

  3. Hvordan kan du køre den samme forespørgsel flere gange ved hjælp af loop i PL/SQL?

  4. Serverens tidszoneværdi 'AEST' er ikke genkendt eller repræsenterer mere end én tidszone