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