Reputation: 707
I have a table called test
and I sort it by the upper range of a range called daterange
. I want to take the order of this sorted data and save it in another column of the same table named bc_order
.
The order of the sort must be saved in the bc_order
column.
So I order the data I want, I loop through the results and I increase a counter every time, then update the bc_order
column with the current counter.
CREATE OR REPLACE FUNCTION __a_bc_order() RETURNS void AS $$
DECLARE
iterator integer := 1;
r test%rowtype;
BEGIN
for r in
select * from test where upper(test.daterange)<0 order by upper(test.daterange) DESC
loop
update test SET bc_order = iterator where test.id = test.id ;
iterator := iterator + 1;
end loop ;
END
$$ LANGUAGE plpgsql;
select __a_bc_order();
I was hoping can get something like
id daterange bc_order
14 [-3001011,-2000101) 1
21 [-3001202,-3000102) 2
19 [-3010102,-3000102) 3
22 [-4001202,-4000102) 4
23 [-4000702,-4000302) 5
27 [-6000401,-6000201) 6
26 [-6000501,-6000301) 7
but I get
id daterange bc_order
14 [-3001011,-2000101) 7
21 [-3001202,-3000102) 7
19 [-3010102,-3000102) 7
22 [-4001202,-4000102) 7
23 [-4000702,-4000302) 7
27 [-6000401,-6000201) 7
26 [-6000501,-6000301) 7
I guess there is an issue with the looping that I cannot fix. Please advice. I use PostgreSQL 10
Upvotes: 0
Views: 3646
Reputation: 45910
Your code is wrong.
update test SET bc_order = iterator where test.id = test.id ;
it is effectively
update test SET bc_order = iterator where true;
and it is exactly your result.
should be
update test SET bc_order = iterator where test.id = r.id;
@a_horse_with_no_name helps well - what is possible with readable one SQL statement, should be done by one SQL query.
Upvotes: 2
Reputation:
No need to use a loop or PL/pgSQL:
update test
set bc_order = t.rn
from (
select id, row_number() over (order by upper(daterange) desc) as rn
from test
upper(daterange) < 0
) t
where t.id = test.id;
Upvotes: 2