Home > Mobile >  How to select a single element with subquery while insertion and update the same table with given re
How to select a single element with subquery while insertion and update the same table with given re

Time:06-09

I have a table, let's say, tableList

unique_id next_id randomCol1
4 5 string 1
5 6 string 2
6 0 string 3

Where unique_id is auto increment column and next_id is the unique_id of the row it is pointing to. At present we have 4->5->6->0(0 is a Non existing row). Now I want to do an insertion of a row next to a given unique_Id, Let's say next to unique_Id=4.
At the time of insertion I want to extract the next_id(5) of the given unique_id(here, 4). The row which I'm about to insert will have next_id = 5 and row with unique_id = 4 will update its next_id to 7 (or whatever unique_id was generated at the time of insertion) So, My table will look like : 4->7->5->6->0

unique_id next_id randomCol1
4 7 string 1
5 6 string 2
6 0 string 3
7 5 string 4

I tried :

Insert into tableList(randomCol1,next_id)
values('string 4', select next_id from tableList where unique_id=4) returning unique_id as current_ID 
Update tableList set next_id = current_id where unique_id=4

Explanation : I'm trying to insert randomCol1 and next_id where next_id needs to be selected from given unique_id. Hence, a sub query for that. I want to update the next_id of given unique_id with whatever unique_id was returned after insertion in same query. But My subquery and update in the same query with returning id is not working.

CodePudding user response:

demo:db<>fiddle

You can use a chain of WITH clauses:

WITH select_part AS (       -- 1
    SELECT next_id
    FROM tableList
    WHERE unique_id = 4
),
insert_part AS (            -- 2
    INSERT INTO tableList ("next_id", "randomCol1")
        SELECT next_id, 'my new string'
        FROM select_part
    RETURNING unique_id
)
UPDATE tableList t          -- 3
SET next_id = i.unique_id
FROM (
    SELECT * 
    FROM insert_part
) i
WHERE t.unique_id = 4
  1. SELECT the next_id value from the row with unique_id = 4
  2. Use this value in the INSERT statement and return the new generated id.
  3. Use the new id to UPDATE the original row.

However, you might think about a separate function to do this.

demo:db<>fiddle

CREATE OR REPLACE FUNCTION insert_value (
    _unique_id int, 
    _my_string text
) RETURNS void
AS $$
DECLARE 
    _next_val int;
    _new_id int;
BEGIN
    SELECT
        next_id
    FROM tableList
    WHERE unique_id = _unique_id
    INTO _next_val;
        
    INSERT INTO tableList("next_id", "randomCol1")
    VALUES (_next_val, _my_string)
    RETURNING unique_id
    INTO _new_id;
    
    UPDATE tableList t
    SET next_id = _new_id
    WHERE unique_id = _unique_id;
END;
$$ LANGUAGE plpgsql

Call it with:

SELECT insert_value(4, 'my_string');
  • Related