我最近刚将一些hibernate映射类的语义更改为列表。添加列表索引列本身是微不足道的,但以合理的方式填充它似乎不那么简单。我结束了编写以下存储过程(PL / pgsql),它通过循环遍历引用列排序的表的所有行并将索引设置为0,1,2,3等,直到找到新的引用号为止。 。它解决了这个问题,但我想知道是否有更简单的方法来实现相同的结果。
CREATE OR REPLACE FUNCTION setlistorderfunc(VARCHAR, VARCHAR) RETURNS VOID AS $$
DECLARE
currIndex INTEGER := 0;
currResource INTEGER := 0;
r RECORD;
BEGIN
FOR r IN execute 'SELECT id id, '|| $2 || ' res, resource_list_order rlo FROM ' || $1 || ' ORDER BY res ASC, rlo ASC' LOOP
IF currResource != r.res THEN
currResource := r.res;
currIndex := 0;
ELSE
currIndex := currIndex + 1;
END IF;
EXECUTE 'UPDATE ' || $1 || ' set resource_list_order = ' || currIndex || 'WHERE id = ' || r.id;
END LOOP;
END;
$$ LANGUAGE plpgsql;
要在资源上升级一包rating
(由名为about_resource
的列链接),请执行以下操作:
SELECT setlistorderfunc('rating', 'about_resource');
答案 0 :(得分:1)
在子查询中使用window function row_number()
,并加入UPDATE
中的结果,以大大简化此操作:
UPDATE rating r
SET resource_list_order = sub.rn
FROM (
SELECT id, row_number() OVER (PARTITION BY about_resource
ORDER BY resource_list_order) - 1 AS rn
FROM rating
) sub
WHERE r.id = sub.id;