188

I have a table that I am trying to update multiple values at once. Here is the table schema:

    Column     |  Type   | Modifiers 
---------------+---------+-----------
 user_id       | integer | 
 subservice_id | integer |

I have the user_id and want to insert multiple subservice_id's at once. Is there a syntax in Postgres that will let me do something like this

insert into user_subservices(user_id, subservice_id) values(1, [1, 2, 3]);

How would I do this?

1

8 Answers 8

295

Multi-value insert syntax is:

insert into table_name values (1,1), (1,2), (1,3), (2,1);

When you need to specify columns:

insert into table_name (user_id, subservice_id) values
  (1, 1),
  (1, 2),
  (1, 3),
  (2, 1);

When you need to get the inserted id for example:

insert into table_name (user_id, subservice_id) values
  (1, 1),
  (1, 2),
  (1, 3),
  (2, 1)
returning id;
Sign up to request clarification or add additional context in comments.

7 Comments

Yes, use returning. "insert into table (id, yada) values (1,2),(9,22) returning id;" etc
Also nowadays a CTE aka WITH statement often works well.
@sankarmuniyappa you'll have to use single quotes ' ' for the text that you're inserting. so something like, insert into orders_cancel_reasons_infos values (1,1,'Changed my mind',1), (2,2,'Quality not satisfactory',1) will work. You can check this out for more on single and double-quotes.
This has the advantage of not being specific to Postgres too.
Not sure why krokodilko's answer is 'much slicker'... I think this should be the accepted answer as this is SQL standard syntax and also much easier to understand.
|
99

Try:

INSERT INTO user_subservices(user_id, subservice_id) 
SELECT 1 id, x
FROM    unnest(ARRAY[1,2,3,4,5,6,7,8,22,33]) x

Demo: http://www.sqlfiddle.com/#!15/9a006/1

1 Comment

I do not agree that using unnest should be the accepted answer, slick as it is. Default syntax is as mentioned by Scott. If you are on my team and use unnest I will ask you why and if you don't have a good answer, I will ask you to change it to the standard syntax
61

A shorter version of krokodilko's answer:

insert into user_subservices(user_id, subservice_id) 
values(1, unnest(array[1, 2, 3]));

5 Comments

I think this is more expressive of intent than the accepted answer. Is this standard SQL or PostgreSQL-specific?
Both answers are PostgreSQL-specific. The accepted answer is perhaps more easily translated to other databases, Oracle for example: insert into user_subservices(user_id, subservice_id) select 1, column_value from table(sys.odcinumberlist(1,2,3)).
Thanks, this makes a lot more sense and is more readable than the accepted answer in my opinion.
A way to use this with information from another table: insert into user_subservices(user_id, subservice_id) values(1, unnest(ARRAY(select id from subservices where name like '%test%')));
Why would you use non-standard syntax for something that is so widely implemented and has been in the SQL standard for decades? Use the syntax from Scott Marlowe's answer as it is standard and works on most DBs unchanged. And is understood by any dev that knows standard SQL.
22

A slightly related answer because I keep finding this question every time I try to remember this solution. Insert multiple rows with multiple columns:

insert into user_subservices (user_id, subservice_id)
select *
from unnest(array[1, 2], array[3, 4]);

1 Comment

Or you can insert an array of integers into one column.
4

More robust example, for when you need to insert multiple rows into some table for every row in another table:

INSERT INTO user_subservices (user_id, subservice_id)
SELECT users.id AS user_id, subservice_id
FROM users
CROSS JOIN unnest(ARRAY[1,2,3]) subservice_id;

Comments

2

A good way to import values once but avoid duplicates is as follows:

insert into schema.mytable (col1,col2) 
select col1, col2 from schema.mytable 
UNION
values 
('row1-col1','row1-col2'),
('row2-col1','row2-col2'),
('row3-col1','row3-col2')
except
select col1, col2 from schema.mytable;

Comments

0

Suppose you want to add the same set of subservice_ids for each of your user, you could make use of CROSS JOIN:

INSERT INTO user_subservices(user_id, subservice_id) 
SELECT
    users.id,
    subservices.id
FROM users
-- Or narrow down the users i.e. only for users with id 1 and 3
-- FROM (SELECT id FROM users WHERE id IN (1, 3)) AS users
CROSS JOIN (
    -- subservice ids to be created for each user
    VALUES
        (1),
        (2),
        (3)
) AS subservices(id);

See sqlfiddle.
You can remove the INSERT INTO statement to view the rows that would be created.
To be safe with your queries, don't forget to use transactions BEGIN and ROLLBACK/COMMIT.

Comments

-2

For multiple values, this function might be helpful.

This function generates multiple values

const _multiInsert = arrOfValues => {
    // removes lastCharacter
    const _remLastChar = str => str.slice(0, str.length - 1);

      let foramttedQuery = '';

      arrOfValues.forEach(row => {
        let newRow = '';
        for (const val of Object.values(row)) {
          let newValue = '';
          if (typeof val === 'string') newValue = `'${val}',`;
          else newValue = `${val},`;
          newRow = newRow.concat(newValue);
        }

        foramttedQuery = foramttedQuery.concat(`(${_remLastChar(newRow)}),`);
      });

      return _remLastChar(foramttedQuery);
    };

    const arr_Of_Values = [
        {
            id: 1,
            name: "SAMPLE_NAME_1",
        },
        {
            id: 2,
            name: "SAMPLE_NAME2",
        }
    ]

    const query_template = `INSERT INTO TABLE_NAME VALUES ${_multiInsert(arr_Of_Values)}`
    
 console.log(query_template)   

2 Comments

WARNING: This example uses non-parametrized queries and it's vulnerable to SQL injection attacks
It would be helpful if you provide an example with parametrize query

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.