我想更新表中列的前10个值。我有三列; id
,account
和accountrank
。为了得到前10个值,我可以使用以下命令:使用PostgreSQL更新前N个值
SELECT * FROM accountrecords
ORDER BY account DESC
LIMIT 10;
我想这样做是accountrank
设定值是一系列1 - 10
的基础上,account
幅度。这可能在PostgreSQL中做到吗?
我想更新表中列的前10个值。我有三列; id
,account
和accountrank
。为了得到前10个值,我可以使用以下命令:使用PostgreSQL更新前N个值
SELECT * FROM accountrecords
ORDER BY account DESC
LIMIT 10;
我想这样做是accountrank
设定值是一系列1 - 10
的基础上,account
幅度。这可能在PostgreSQL中做到吗?
UPDATE accountrecords a
SET accountrank = sub.rn
FROM (
SELECT id, row_number() OVER (ORDER BY account DESC NULLS LAST) AS rn
FROM accountrecords
ORDER BY account DESC NULLS LAST
LIMIT 10
) sub
WHERE sub.id = a.id;
加入表格通常比关联的子查询更快。它也更短。
与window function row_number()
不同的数字是有保证的。如果您希望account
具有相同值的行共享相同的编号,请使用rank()
(或可能为dense_rank()
)。
只有当有可以在account
NULL
值,则需要追加NULLS LAST
为降序排序,或者NULL
值排在最前面:
如果有可能并发写访问,上述查询受竞争条件。试想一下:
但是,如果是这样的话,整个概念硬编码的前十名将开始与一个可疑的做法。
当然,你可以在子查询中使用你的select语句。生成排名并不重要,但至少有一种方法可以实现。我没有测试过这一点,但我的头顶部:
update accountrecords
set accountrank =
(select count(*) + 1 from accountrecords r where r.account > account)
where id in (select id from accountrecords order by account desc limit 10);
这有怪癖,如果两个记录具有相同的价值account
,那么他们将得到相同的等级。您可以考虑一个功能... :-)
如果您的poatgres版本是8.4或以上,您可以使用窗口函数+ rank()或row_number()。 – wildplasser