Update top N values using PostgreSQL

后端 未结 2 2193
-上瘾入骨i
-上瘾入骨i 2021-02-19 07:47

I want to update the top 10 values of a column in table. I have three columns; id, account and accountrank. To get the top 10 values I can

2条回答
  •  情歌与酒
    2021-02-19 08: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;
    

    Joining in a table expression is typically faster than correlated subqueries. It is also shorter.

    With the window function row_number() distinct numbers are guaranteed. Use rank() (or possibly dense_rank()) if you want rows with equal values for account to share the same number.

    Only if there can be NULL values in account, you need to append NULLS LAST for descending sort order, or NULL values sort on top:

    • PostgreSQL sort by datetime asc, null first?

    If there can be concurrent write access, the above query is subject to a race condition. Consider:

    • Atomic UPDATE .. SELECT in Postgres
    • Postgres UPDATE … LIMIT 1

    However, if that was the case, the whole concept of hard-coding the top ten would be a dubious approach to begin with.

    Use a CTE instead of a plain subquery (like I had at first) to enforce the LIMIT reliably. See links above.

提交回复
热议问题