我想更新表中列的前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