plpgsql循环查询和更新

时间:2018-04-12 17:23:07

标签: postgresql loops sorting sql-update plpgsql

我有一个名为test的表,我按名为daterange的范围的上限进行排序。我想取这个排序数据的顺序,并将其保存在名为bc_order的同一个表的另一列中。

排序顺序必须保存在bc_order列中。

所以我订购了我想要的数据,我遍历结果并每次增加一个计数器,然后用当前计数器更新bc_order列。

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();

我希望能得到像

这样的东西
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

但我得到

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

我想循环中存在一个我无法解决的问题。请指教。我使用PostgreSQL 10

2 个答案:

答案 0 :(得分:1)

无需使用循环或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;

答案 1 :(得分:1)

你的代码错了。

update test SET bc_order  = iterator where test.id = test.id ; 

它实际上是

update test SET bc_order  = iterator where true; 

这正是你的结果。

应该是

update test SET bc_order  = iterator where test.id = r.id; 

@a_horse_with_no_name很有帮助 - 可读的一个SQL语句可以通过一个SQL查询来完成。