使用PostgreSQL更新前N个值

djq*_*djq 12 sql postgresql sql-order-by sql-update sql-limit

我想更新表中列的前10个值.我有三列; id,accountaccountrank.要获得前10个值,我可以使用以下内容:

SELECT  * FROM accountrecords    
ORDER BY account DESC
LIMIT 10;
Run Code Online (Sandbox Code Playgroud)

我想要做的是根据的大小将值设置accountrank为一系列.这可以在PostgreSQL中做到吗?1 - 10account

Erw*_*ter 26

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;
Run Code Online (Sandbox Code Playgroud)

加入表表达式通常比相关子查询更快.它也更短.

使用窗口功能row_number()可以保证不同的数字.如果希望具有相同值的行共享相同的数字,请使用rank()(或可能dense_rank())account.

只有可以存在NULL值时account,您需要附加NULLS LAST降序排序,或者NULL值排序在顶部:

如果可以进行并发写访问,则上述查询将受到竞争条件的影响.考虑:

但是,如果是这种情况,那么硬编码前十名的整个概念将是一个可疑的方法.

使用CTE而不是普通的子查询(就像我最初那样)来LIMIT可靠地强制执行.见上面的链接.