Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL (postgres) RETURNING data from multiple tables after an INSERT INTO / UPDATE

Is it possible in postgres to return data from multiple tables after 1) An INSERT INTO, and 2) an UPDATE?

For example, supposing the following contrived example:

review             fit
------             ----
id                 id
fit_id             label
body

1) How can I insert into the review table and return the respective fit data joined with the review data in the RETURNING clause?

So, SQL to insert without accomplishing the desired result:

INSERT INTO review (id, fit_id, body) VALUES (5, 1, 'some copy') RETURNING *;

However, the desired result is:

id     | 5
fit_id | 1
body   | some copy
id     | 1
label  | some label

2) How can I update the review fit_id and return the new fit data joined with the review data in the RETURNING clause?

SQL to update the fit_id to 2 of review 5 without accomplishing the desired result:

UPDATE review SET fit_id = 2 WHERE review_id = 5 RETURNING *;

However, the desired result is:

id     | 5
fit_id | 2
body   | some copy
id     | 2
label  | some other label
like image 972
craigmichaelmartin Avatar asked Mar 28 '18 13:03

craigmichaelmartin


People also ask

What does Postgres return on INSERT?

In an INSERT , the data available to RETURNING is the row as it was inserted. This is not so useful in trivial inserts, since it would just repeat the data provided by the client. But it can be very handy when relying on computed default values.

What is needed for an INSERT on conflict update to work?

You must have INSERT privilege on a table in order to insert into it. If ON CONFLICT DO UPDATE is present, UPDATE privilege on the table is also required. If a column list is specified, you only need INSERT privilege on the listed columns.

What is select for update Postgres?

The select ... for update acquires a ROW SHARE LOCK on a table. This lock conflicts with the EXCLUSIVE lock needed for an update statement, and prevents any changes that could happen concurrently. All the locks will be released when the transaction ends.


1 Answers

WITH inserted AS (
    INSERT INTO review VALUES (...) RETURNING *
)
SELECT inserted.*, fit.*
FROM inserted
INNER JOIN fit ON inserted.fit_id = fit.id

That will get you the output you want. Pretty sure you can't return stuff from another table in an UPDATE/INSERT ... RETURNING statement.

like image 98
404 Avatar answered Nov 18 '22 13:11

404