2012-11-02 28 views
9

Tôi muốn cập nhật 10 giá trị hàng đầu của một cột trong bảng. Tôi có ba cột; id, accountaccountrank. Để có được 10 giá trị đầu tôi có thể sử dụng như sau:Cập nhật giá trị N cao nhất bằng cách sử dụng PostgreSQL

SELECT * FROM accountrecords  
ORDER BY account DESC 
LIMIT 10; 

Những gì tôi muốn làm là để thiết lập giá trị trong accountrank là một loạt các 1 - 10, dựa trên tầm quan trọng của account. Điều này có thể thực hiện trong PostgreSQL không?

+2

Nếu phiên bản poatgres của bạn là 8.4 hoặc cao hơn, bạn có thể sử dụng chức năng cửa sổ + rank() hoặc row_number(). – wildplasser

Trả lời

22
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; 

Tham gia vào bảng thường nhanh hơn các truy vấn con tương quan. Nó cũng ngắn hơn.

Với số window function row_number() riêng biệt được đảm bảo. Sử dụng rank() (hoặc có thể dense_rank()) nếu bạn muốn các hàng có giá trị bằng nhau cho account để chia sẻ cùng một số.

Chỉ khi có thể có NULL giá trị trong account, bạn cần phải thêm NULLS LAST cho giảm dần thứ tự sắp xếp, hoặc NULL giá trị sắp xếp trên top:

Nếu có thể có đồng thời ghi truy cập, truy vấn ở trên phải tuân theo điều kiện chủng tộc đua. Xem xét:

Tuy nhiên, nếu đó là trường hợp, toàn bộ khái niệm về cứng mã hóa top mười sẽ là một cách tiếp cận đáng ngờ để bắt đầu với.

1

Chắc chắn, bạn có thể sử dụng câu lệnh chọn trong truy vấn phụ. Tạo thứ tự xếp hạng không phải là tầm thường, nhưng đây là ít nhất một cách để làm điều đó. Tôi đã không kiểm tra này, nhưng ra khỏi đỉnh đầu của tôi:

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); 

này có những đứa rằng nếu hai kỷ lục có cùng giá trị cho account, sau đó họ sẽ nhận được cùng ngạch. Bạn có thể xem xét một tính năng ... :-)

Các vấn đề liên quan