我想在更新表列的前10个值。 我有三列; id
, account
和accountrank
。 为了得到前10个值,我可以使用以下命令:
SELECT * FROM accountrecords
ORDER BY account DESC
LIMIT 10;
我想要做的是设置在价值accountrank
是一个系列的1 - 10
的基础上的大小account
。 这是可能的PostgreSQL的呢?
我想在更新表列的前10个值。 我有三列; id
, account
和accountrank
。 为了得到前10个值,我可以使用以下命令:
SELECT * FROM accountrecords
ORDER BY account DESC
LIMIT 10;
我想要做的是设置在价值accountrank
是一个系列的1 - 10
的基础上的大小account
。 这是可能的PostgreSQL的呢?
WITH cte AS (
SELECT id, row_number() OVER (ORDER BY account DESC NULLS LAST) AS rn
FROM accountrecords
ORDER BY account DESC NULLS LAST
LIMIT 10
)
UPDATE accountrecords a
SET accountrank = cte.rn
FROM cte
WHERE cte.id = a.id;
在表中表达接合通常比相关子查询更快。 这也是短。
与窗函数row_number()
不同数字有保证。 使用rank()
或可能dense_rank()
如果你想与同等值的行account
共享同一个号码。
只有当可以有NULL
价值观account
,则需要追加NULLS LAST
的降序排列,或NULL
值排在最前面:
如果有可能并发写入访问,上面的查询是受竞争条件 。 考虑:
但是,如果是这样的话,整个概念硬编码的前十名将开始与一个可疑的做法。
使用CTE,而不是一个普通的子查询(如我在第一个)来执行LIMIT
可靠。 见上面的链接。
当然,你可以在一个子查询使用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
,那么他们将得到相同的等级。 你可以认为这是一个功能... :-)