我有一个表segnature
,用于描述带有varchar字段deno
和数字字段ord
的项目。外键fk_collection
告诉该行是哪一个集合。
我想更新字段ord
,以便它包含每个集合的该行的序号,按字段deno排序。
E.g。如果我有类似
的东西[deno] ord [fk_collection]
abc 10
aab 10
bcd 10
zxc 20
vbn 20
然后我想要一个像
这样的结果[deno] ord [fk_collection]
abc 1 10
aab 0 10
bcd 2 10
zxc 1 20
vbn 0 20
我试过像
这样的东西update segnature s1 set ord = (select count(*)
from segnature s2
where s1.fk_collection=s2.fk_collection and s2.deno<s1.deno
)
但查询确实速度慢:每10万分左右就会更新每300件商品150件。
有什么建议加快这个过程吗?
谢谢!
答案 0 :(得分:4)
您可以使用窗口函数生成&#34;序数&#34;号:
with numbered as (
select deno, fk_collection,
row_number() over (partition by fk_collection order by deno) as rn,
ctid as id
from segnature
)
update segnature
set ord = n.rn
from numbered n
where n.id = segnature.ctid;
这使用内部列ctid
来唯一标识每一行。 ctid
比较速度非常慢,因此如果您在该表中有一个真正的主键(或唯一键),请改用该列。
update segnature
set ord = n.rn
from (
select deno, fk_collection,
row_number() over (partition by fk_collection order by deno) as rn,
ctid as id
from segnature
) as n
where n.id = segnature.ctid;
SQLFiddle示例:http://sqlfiddle.com/#!15/e997f/1