131

I'm trying to do something like this in postgres:

  • UPDATE table1 SET (col1, col2) = (SELECT col2, col3 FROM othertable WHERE othertable.col1 = 123);

  • INSERT INTO table1 (col1, col2) VALUES (SELECT col1, col2 FROM othertable)

But point 1 is not possible even with postgres 9.0 as mentioned in the docs (http://www.postgresql.org/docs/9.0/static/sql-update.html)

Also point 2 seems not working. i'm getting the following error: subquery must return only one column.

Hope somebody has a workaround for me. otherwise the queries will take a looot of time :(.

FYI: I'm trying to select different columns from several tables and store them into a temporary table, so that another application can easily fetch the prepared data.

Juan Mellado
  • 14,833
  • 5
  • 45
  • 53
dforce
  • 1,958
  • 3
  • 19
  • 34

3 Answers3

208

For the UPDATE

Use:

UPDATE table1 
   SET col1 = othertable.col2,
       col2 = othertable.col3 
  FROM othertable 
 WHERE othertable.col1 = 123;

For the INSERT

Use:

INSERT INTO table1 (col1, col2) 
SELECT col1, col2 
  FROM othertable

You don't need the VALUES syntax if you are using a SELECT to populate the INSERT values.

Milen A. Radev
  • 57,132
  • 21
  • 101
  • 108
OMG Ponies
  • 314,254
  • 77
  • 507
  • 490
  • 1
    Is it possible to combine Update & Insert so that if one fails, the other will be used without throwing an error (independently for each row). I think that would be a more complete solution to the question (for example: http://stackoverflow.com/a/6527838/781695) – user Dec 24 '14 at 05:08
34

OMG Ponies's answer works perfectly, but just in case you need something more complex, here is an example of a slightly more advanced update query:

UPDATE table1 
SET col1 = subquery.col2,
    col2 = subquery.col3 
FROM (
    SELECT t2.foo as col1, t3.bar as col2, t3.foobar as col3 
    FROM table2 t2 INNER JOIN table3 t3 ON t2.id = t3.t2_id
    WHERE t2.created_at > '2016-01-01'
) AS subquery
WHERE table1.id = subquery.col1;
David Namenyi
  • 587
  • 8
  • 9
16
UPDATE table1 SET (col1, col2) = (col2, col3) FROM othertable WHERE othertable.col1 = 123;
Tim Cooper
  • 151,519
  • 37
  • 317
  • 271
Walter
  • 161
  • 1
  • 2