sql >> Database >  >> RDS >> PostgreSQL

INSERT INTO ... FROM SELECT ... RETURNING id mappings

Dit zou eenvoudiger zijn voor UPDATE , waar extra rijen die zijn toegevoegd aan de update zichtbaar zijn voor de RETURNING clausule:

  • Pre-UPDATE kolomwaarden retourneren met alleen SQL - PostgreSQL-versie

Hetzelfde is momenteel niet mogelijk voor INSERT . Per documentatie:

De expressie kan elke kolomnaam van de tabel gebruiken met de naam tabelnaam

tabelnaam het doel zijn van de INSERT commando.

U kunt (data-modificerende) CTE's gebruiken om dit te laten werken.
Ervan uitgaande dat title om uniek te zijn per zoekopdracht , anders moet je meer doen:

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

Als title is niet uniek per zoekopdracht (maar in ieder geval id is uniek per tafel):

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

Deze tweede query is gebaseerd op het ongedocumenteerde implementatiedetail dat rijen worden ingevoegd in de opgegeven volgorde. Het werkt in alle huidige versies van Postgres en zal waarschijnlijk niet kapot gaan.

SQL Fiddle.



  1. Hoofdlettergevoelige variabelen in SQL Server

  2. Geautomatiseerd testen van het upgradeproces voor PXC/MariaDB Galera Cluster

  3. Gebruik COL_LENGTH() om de lengte van een kolom in SQL Server te krijgen

  4. onbeforeprint() en onafterprint() equivalent voor niet-IE-browsers