Postgres 9.2 PL/pgSQL循环中的简单更新

ell*_*lmo 10 sql postgresql plpgsql postgresql-9.2

我有一张桌子:

+----+----------+----------+
| id | trail_id | position |
+----+----------+----------+
| 11 | 16       | NULL     |
| 12 | 121      | NULL     |
| 15 | 121      | NULL     |
| 19 | 42       | NULL     |
| 20 | 42       | NULL     |
| 21 | 42       | NULL     |
+----+----------+----------+
Run Code Online (Sandbox Code Playgroud)

而且我正在寻找一种简单的方法来position使用递增整数进行更新(每个父级).所以在我完成后,表格应如下所示:

+----+-----------+----------+
| id | trail_id  | position |
+----+-----------+----------+
| 11 | 16        | 1        |
| 12 | 121       | 1        |
| 15 | 121       | 2        |
| 19 | 42        | 1        |
| 20 | 42        | 2        |
| 21 | 42        | 3        |
+----+-----------+----------+
Run Code Online (Sandbox Code Playgroud)

我认为我需要的是一个函数,它遍历给定的所有行trail,具有简单的递增索引并更新position列.我是一个pgSQL新手,所以我很高兴听到有更简单的方法来做到这一点.

我现在正在尝试的解决方案看起来像这样

CREATE FUNCTION fill_positions(tid integer) RETURNS integer AS $$
DECLARE
    pht RECORD;
    i INTEGER := 0;
BEGIN
    FOR pht IN SELECT * FROM photos WHERE photos.trail_id = tid LOOP
        i := i + 1;
        UPDATE photos SET position = i WHERE id = pht.id;
    END LOOP;
    RETURN i;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

我很确定它可以更干净,而且不必使用功能.

a_h*_*ame 15

您不需要存储函数.你可以用一个语句来做到这一点.

with new_numbers as (
   select id,  
          trail_id,
          row_number() over (partition by trail_id order by id) as position
   from photos
)
update photos
  set position = nn.position
from new_numbers nn
where nn.id = photos.id;
Run Code Online (Sandbox Code Playgroud)