agora inbox for pgsql-sql@postgresql.org  
help / color / mirror / Atom feed
From: Andreas Joseph Krogh <andreas@visena.com>
To: pgsql-sql@postgresql.org
Subject: Re: Unable to use INSERT ... RETURNING with column from other table
Date: Wed, 25 Oct 2017 02:21:19 +0200 (CEST)
Message-ID: <VisenaEmail.5f.363e3023a414a542.15f50dcaa73@tc7-visena> (raw)
In-Reply-To: <VisenaEmail.5e.f9aed09bf35804e1.15f509189ac@tc7-visena>
List-Unsubscribe: <mailto:majordomo@postgresql.org?body=unsub%20pgsql-sql>

På onsdag 25. oktober 2017 kl. 00:49:05, skrev Andreas Joseph Krogh <
andreas@visena.com <mailto:andreas@visena.com>>:
På onsdag 25. oktober 2017 kl. 00:06:59, skrev Peter Geoghegan <pg@bowt.ie 
<mailto:pg@bowt.ie>>:
On Tue, Oct 24, 2017 at 3:04 PM, Andreas Joseph Krogh
 <andreas@visena.com> wrote:
 > insert into foo(id, name) values(1, 'one'), (2, 'two');
 >
 > insert into foo(id, name) select 3, f.name from foo f where f.id = 1 
returning id, f.id;
 >
 > ERROR:  missing FROM-clause entry for table "f"
 > LINE 1: ...lect 3, f.name from foo f where f.id = 1 returning id, f.id;
 >
 > I'd like to return f.id and the inserted id, is this possible?

 It's possible on 9.5+. You need to assign the target table an alias
 using AS -- AS in not a noise word for INSERT (the grammar requires
 it).

 See the INSERT documentation.
 
I'm not sure how an alias for the target_table will help me here as I'm trying 
to return a value not being inserted?
f.id is not inserted, only columns matching f.id.
 
 
 
What I want to accomplish is returning a value from INSERT which is part of 
the SELECT-expression's FROM-clause, not part of the actual inserted columns:
 
My real-world use-case isn't quite this simple but this sample-case 
illustrates the problem;
 
DROP TABLE IF EXISTS tbl_value; DROP TABLE IF EXISTS tbl_header; CREATE TABLE 
tbl_header( idINTEGER PRIMARY KEY, name VARCHAR NOT NULL ); CREATE TABLE 
tbl_value( idSERIAL PRIMARY KEY, header_id INTEGER NOT NULL REFERENCES 
tbl_header(id),name VARCHAR NOT NULL ); INSERT INTO tbl_header(id, name) VALUES(
1, 'header_one'), (2, 'header_two'); INSERT INTO tbl_value(id, header_id, name) 
VALUES(1, 1, 'value 1'),(2, 1, 'value 2'),(3, 1, 'value 3') , (4, 2, 'value 1'
),(5, 2, 'value 2'),(6, 2, 'value 3'); SELECT setval('tbl_value_id_seq', 6); 
WITHupd_h(new_header_id, header_name, old_header_id) AS ( INSERT INTO 
tbl_header(id,name) SELECT 3, h.name FROM tbl_header h WHERE h.id = 1 RETURNING 
id,name, 1 -- need h.id here ) INSERT INTO tbl_value(header_id, name) SELECT 
f.new_header_id, hv.nameFROM tbl_value hv JOIN tbl_header h ON hv.header_id = h
.idJOIN upd_h AS f ON hv.header_id = f.old_header_id ; select h.*, v.* from 
tbl_headerh JOIN tbl_value v ON v.header_id = h.id ORDER BY h.id, v.id;  
id name id header_id name 1 header_one 1 1 value 1 1 header_one 2 1 value 2 1 
header_one 3 1 value 3 2 header_two 4 2 value 1 2 header_two 5 2 value 2 2 
header_two 6 2 value 3 3 header_one 7 3 value 1 3 header_one 8 3 value 2 3 
header_one 9 3 value 3 

 
 
 
I need to return the value for h.id in the first INSERT:
 
WITH upd_h(new_header_id, header_name, old_header_id) AS ( INSERT INTO 
tbl_header(id,name) SELECT 3, h.name FROM tbl_header h WHERE h.id = 1 RETURNING 
id,name, h.id ) INSERT INTO tbl_value(header_id, name) SELECT f.new_header_id, 
hv.nameFROM tbl_value hv JOIN tbl_header h ON hv.header_id = h.id JOIN upd_h AS 
fON hv.header_id = f.old_header_id ;  
This fails with:
ERROR:  missing FROM-clause entry for table "h" 
 LINE 5:     RETURNING id, name, h.id

  
Is what I'm trying to do possible? I'd like to avoid having to use temp-tables 
and/or PLPgSQL for this as I need to insert many such values in large batches...
 
Thanks.
 

-- Andreas Joseph Krogh
CTO / Partner - Visena AS
Mobile: +47 909 56 963
andreas@visena.com <mailto:andreas@visena.com>
www.visena.com <https://www.visena.com;
 <https://www.visena.com;


 

view thread (9+ messages)  latest in thread

Message-ID: <VisenaEmail.5f.363e3023a414a542.15f50dcaa73@tc7-visena>
Permalink:  ../VisenaEmail.5f.363e3023a414a542.15f50dcaa73@tc7-visena/
Also on:    postgresql.org/message-id/VisenaEmail.5f.363e3023a414a542.15f50dcaa73@tc7-visena

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-sql@postgresql.org
  Cc: andreas@visena.com
  Subject: Re: Unable to use INSERT ... RETURNING with column from other table
  In-Reply-To: <VisenaEmail.5f.363e3023a414a542.15f50dcaa73@tc7-visena>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox