The list of users that I am copying from already associated with orgs, is there an easy way to build my query based on that, given that newly created users have different keys?
If there is any subset of columns to identify unique user without PK, there is a secure solution with data-modifying CTEs. You could even insert multiple user-copies at once:
WITH template_user AS (
SELECT u.*, uo.org_id -- include the connected org_id
FROM users u
JOIN user_org uo ON uo.user_id = u.id -- guessing column names
WHERE ... -- make sure exactly *one* desired org is joined
)
, ins_user AS (
INSERT INTO users u (...)
SELECT ...
FROM template_user t
WHERE ...
RETURNING *
)
INSERT INTO user_org (user_id, org_id)
SELECT iu.id, tu.org_id
FROM ins_user iu
JOIN template_user tu USING (<list of columns that secures distinct join>)
RETURNING *; -- optional
In the unlikely case that you shouldn't have a reliable set of columns to join to the template users: add a row number, like @sgeddes already suggested, but in a query that actually works:
WITH template_usr AS (
SELECT u.*, uo.org_id -- include the connected org_id
row_number() OVER () AS rn -- arbitrary number
FROM usr u
JOIN usr_org uo ON uo.usr_id = u.id -- guessing column names
WHERE ... -- make sure exactly *one* desired org is joined
)
, ins_usr AS (
INSERT INTO usr u (...) -- add target columns
SELECT ...
FROM template_usr
ORDER BY rn -- insert in same order!
RETURNING id
)
INSERT INTO usr_org (usr_id, org_id)
SELECT iu.id, tu.org_id
FROM (
SELECT id, row_number() OVER (ORDER BY id) AS rn
FROM ins_usr
) iu
JOIN template_usr tu USING (rn)
RETURNING *; -- optional
Related: