PostgreSQL:设置一个列,其中的行序号通过另一个字段排序
我有一个表segnature,它用一个varchar字段deno和一个数值字段ord描述一个项。外键fk_集合告诉行是哪个集合的一部分 我想更新字段ord,以便它包含每个集合中该行的序号,按字段deno排序 例如,如果我有PostgreSQL:设置一个列,其中的行序号通过另一个字段排序,postgresql,Postgresql,我有一个表segnature,它用一个varchar字段deno和一个数值字段ord描述一个项。外键fk_集合告诉行是哪个集合的一部分 我想更新字段ord,以便它包含每个集合中该行的序号,按字段deno排序 例如,如果我有 [deno] ord [fk_collection] abc 10 aab 10 bcd 10 zxc 20 vbn 20 upda
[deno] ord [fk_collection]
abc 10
aab 10
bcd 10
zxc 20
vbn 20
update segnature s1 set ord = (select count(*)
from segnature s2
where s1.fk_collection=s2.fk_collection and s2.deno<s1.deno
)
然后我想要一个这样的结果
[deno] ord [fk_collection]
abc 1 10
aab 0 10
bcd 2 10
zxc 1 20
vbn 0 20
我试过用类似的东西
[deno] ord [fk_collection]
abc 10
aab 10
bcd 10
zxc 20
vbn 20
update segnature s1 set ord = (select count(*)
from segnature s2
where s1.fk_collection=s2.fk_collection and s2.deno<s1.deno
)
但查询速度真的很慢:每30000个项目中有150个集合在10分钟左右更新
有没有加快这一进程的建议
谢谢大家! 您可以使用窗口函数生成序号:
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比较非常慢,因此如果该表中有真正的主键或唯一键,请使用该列
或者,如果没有:
SQLFiddle示例:Perfect:我在每一行上都有一个pk_id,所以我调整了您的查询以使用pk,现在它就像一个符咒:大约1秒对10分钟是一个巨大的改进!我不知道窗口的功能,我必须学习它们是如何工作的。非常感谢你!