postgres 使用 CTE 插入并在下一个子查询中使用 inersted id
postgres insert using CTE and use the inersted id in next sub query
我将一个用户插入到数据库中。然后我需要生成的用户 ID 插入 teamMember
table。我正在使用 CTE,我同时读取它们 运行,是否可以 return 插入用户的 id 到下一个语句?
with INPUT (col) as (
VALUES ('
{
"insert":[
{"username":"JSmith", "name":"John Smith", "mail":"JSmith@smith.com","jobTitle":"Lead","hasImage":true,"teamId":47}
],
"delete":[
],
"update":[{"username":"JDoe", "name":"Jane Doe","mail":"JDoe@mark.com","jobTitle":"Software Developer","hasImage":false, "uid": 255, "teamId":40}]
}'::jsonb)
),
-- Insert new users if username is unique
do_insert as (
INSERT INTO users (username, name, mail, "jobTitle", "hasImage")
SELECT i.value ->> 'username',
i.value ->> 'name',
i.value ->> 'mail',
i.value ->> 'jobTitle',
(i.value ->> 'hasImage')::boolean
FROM INPUT
CROSS JOIN json_array_elements(to_json(col -> 'insert')) i
WHERE NOT EXISTS (
SELECT (username) FROM users
WHERE username = i.value ->> 'username'
)
RETURNING *
)
-- Insert row in teamMembers
INSERT INTO "teamMembers"("teamId", "userId")
select (i.value ->> 'teamId')::int, t1.id
from input
cross join json_array_elements(to_json(col -> 'insert')) i
left join users t1 ON i.value ->> 'username' = t1.username
left join do_insert on users.username = do_insert.username
您不需要 users
上的左连接,因为 do_insert
与 table 相同但已更新。在您的 select 中,将 do_insert.id
替换为 t1.id
并删除 left join 的用户,它应该可以工作。
with INPUT (col) as (
VALUES ('
{
"insert":[
{"username":"JSmith", "name":"John Smith", "mail":"JSmith@smith.com","jobTitle":"Lead","hasImage":true,"teamId":47}
],
"delete":[
],
"update":[{"username":"JDoe", "name":"Jane Doe","mail":"JDoe@mark.com","jobTitle":"Software Developer","hasImage":false, "uid": 255, "teamId":40}]
}'::jsonb)
),
-- Insert new users if username is unique
do_insert as (
INSERT INTO users (username, name, mail, "jobTitle", "hasImage")
SELECT i.value ->> 'username',
i.value ->> 'name',
i.value ->> 'mail',
i.value ->> 'jobTitle',
(i.value ->> 'hasImage')::boolean
FROM INPUT
CROSS JOIN json_array_elements(to_json(col -> 'insert')) i
WHERE NOT EXISTS (
SELECT (username) FROM users
WHERE username = i.value ->> 'username'
)
RETURNING *
)
-- Insert row in teamMembers
INSERT INTO "teamMembers"("teamId", "userId")
select (i.value ->> 'teamId')::int, do_insert.id
from input
cross join json_array_elements(to_json(col -> 'insert')) i
left join do_insert on users.username = do_insert.username
我将一个用户插入到数据库中。然后我需要生成的用户 ID 插入 teamMember
table。我正在使用 CTE,我同时读取它们 运行,是否可以 return 插入用户的 id 到下一个语句?
with INPUT (col) as (
VALUES ('
{
"insert":[
{"username":"JSmith", "name":"John Smith", "mail":"JSmith@smith.com","jobTitle":"Lead","hasImage":true,"teamId":47}
],
"delete":[
],
"update":[{"username":"JDoe", "name":"Jane Doe","mail":"JDoe@mark.com","jobTitle":"Software Developer","hasImage":false, "uid": 255, "teamId":40}]
}'::jsonb)
),
-- Insert new users if username is unique
do_insert as (
INSERT INTO users (username, name, mail, "jobTitle", "hasImage")
SELECT i.value ->> 'username',
i.value ->> 'name',
i.value ->> 'mail',
i.value ->> 'jobTitle',
(i.value ->> 'hasImage')::boolean
FROM INPUT
CROSS JOIN json_array_elements(to_json(col -> 'insert')) i
WHERE NOT EXISTS (
SELECT (username) FROM users
WHERE username = i.value ->> 'username'
)
RETURNING *
)
-- Insert row in teamMembers
INSERT INTO "teamMembers"("teamId", "userId")
select (i.value ->> 'teamId')::int, t1.id
from input
cross join json_array_elements(to_json(col -> 'insert')) i
left join users t1 ON i.value ->> 'username' = t1.username
left join do_insert on users.username = do_insert.username
您不需要 users
上的左连接,因为 do_insert
与 table 相同但已更新。在您的 select 中,将 do_insert.id
替换为 t1.id
并删除 left join 的用户,它应该可以工作。
with INPUT (col) as (
VALUES ('
{
"insert":[
{"username":"JSmith", "name":"John Smith", "mail":"JSmith@smith.com","jobTitle":"Lead","hasImage":true,"teamId":47}
],
"delete":[
],
"update":[{"username":"JDoe", "name":"Jane Doe","mail":"JDoe@mark.com","jobTitle":"Software Developer","hasImage":false, "uid": 255, "teamId":40}]
}'::jsonb)
),
-- Insert new users if username is unique
do_insert as (
INSERT INTO users (username, name, mail, "jobTitle", "hasImage")
SELECT i.value ->> 'username',
i.value ->> 'name',
i.value ->> 'mail',
i.value ->> 'jobTitle',
(i.value ->> 'hasImage')::boolean
FROM INPUT
CROSS JOIN json_array_elements(to_json(col -> 'insert')) i
WHERE NOT EXISTS (
SELECT (username) FROM users
WHERE username = i.value ->> 'username'
)
RETURNING *
)
-- Insert row in teamMembers
INSERT INTO "teamMembers"("teamId", "userId")
select (i.value ->> 'teamId')::int, do_insert.id
from input
cross join json_array_elements(to_json(col -> 'insert')) i
left join do_insert on users.username = do_insert.username