Home > Net >  PostgreSQL - How to use the result of previous record to insert a new record
PostgreSQL - How to use the result of previous record to insert a new record

Time:05-11

I am trying to write a migration for my customer table where the my new column new_number should get incremental values (starting from 10000 because of a business rule) for each company like the following:

id company_id new_number
1 1 10000
2 1 10001
3 1 10002
4 2 10000
5 2 10001

I have written a query that does the trick by using a function that fetches the last inserted number and adds 1 to the new row. But is way too slow and causes timeout when run on thousands of rows.

create or replace function get_number (id_company uuid)
returns int
language plpgsql
as
$$
declare
new_number integer;
begin
select
    c.new_number
into new_number
from
   customer c
where
  c.company_id = id_company
  and c.new_number is not null
order by c.new_number desc
limit 1;
return new_number;
end;
$$;

update
   customer c
set
    new_number =
        case
            when get_number(c.company_id) is null then 1 else get_number(c.company_id)   1
            end
where c.new_number is null;

Is there a simpler way to achieve what I am trying to do?

Thank you in advance!

CodePudding user response:

You could avoid a UDF and instead use an update join with the help of ROW_NUMBER:

UPDATE customer AS c1 
SET new_number = c2.rn
FROM
(
    SELECT id, ROW_NUMBER() OVER (PARTITION BY company_id ORDER BY id) rn
    FROM customer
) c2
WHERE c1.id = c2.id;

CodePudding user response:

if I understand correctly you can try to ROW_NUMBER window function instead of function.

WITH cte AS (
    SELECT *,ROW_NUMBER() OVER(PARTITION BY company_id ORDER BY id) rn
    FROM customer 
)
UPDATE customer t1
SET new_number = cte.rn   9999
FROM cte
WHERE t1.new_number IS NULL AND t1.id = cte.id
  • Related