2

In Postgres (version 9.4 fwiw), an INSERT INTO ... SELECT query seems to insert based on column position rather than name:

pg=# CREATE TEMPORARY TABLE x (a int, b int);
CREATE TABLE
pg=# INSERT INTO x (a, b) SELECT 1 as b, 2 as a;
INSERT 0 1
pg=# SELECT * FROM x;
 a | b
---+---
 1 | 2
(1 row)

Is there any way to structure this query or something similar such that the columns would be inserted by name rather than positionally? I would want the result here to be:

pg=# SELECT * FROM x;
 a | b
---+---
 2 | 1
(1 row)

The context here is that the contents of the SELECT are being defined in a different place than the overall INSERT call, so it's difficult to enforce a common order.

2
  • 1
    There is no way to do this in SQL. Commented Feb 7, 2017 at 15:35
  • @LaurenzAlbe check out the clever answer below! Commented Feb 8, 2017 at 12:26

2 Answers 2

1

Simply move the query to a subquery:

INSERT INTO x (a, b) SELECT a, b FROM (SELECT 1 AS b, 2 AS a) src;
Sign up to request clarification or add additional context in comments.

1 Comment

Ah, that's a great solution! Thank you :)
0

You define the order of the columns with the insert statement:

INSERT INTO x (b, a) 
SELECT 1 as b, -- maps to first column above
       2 as a; -- maps to second column above

2 Comments

Right, this much is clear, but I want this to work even if the order between the two parts of the query don't match... I'll clarify the question.
@nicolaskruchten I see what you're saying... Bottom line is, with an insert ... select, the values in the select will insert in the order defined in the parentheses of the INSERT

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.