2012-11-02 9 views
9

테이블에있는 열의 상위 10 개 값을 업데이트하고 싶습니다. 나는 세 개의 기둥을 가지고있다. id, accountaccountrank. 상위 10의 값을 얻기 위해 나는 다음을 사용할 수 있습니다PostgreSQL을 사용하여 상위 N 개의 값을 업데이트하십시오.

SELECT * FROM accountrecords  
ORDER BY account DESC 
LIMIT 10; 

는 내가 뭘하고 싶은 account의 크기에 따라 1 - 10의 시리즈로 accountrank의 값을 설정하는 것입니다. 이것이 PostgreSQL에서 가능합니까?

+2

poatgres 버전이 8.4 이상이면 윈도우 함수 + rank() 또는 row_number()를 사용할 수 있습니다. – wildplasser

답변

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; 

일반적으로 테이블에 조인하는 것은 상관 관계가있는 하위 쿼리보다 빠릅니다. 또한 더 짧습니다.

window function row_number()은 고유 번호가 보장됩니다. account에 대해 동일한 값을 가진 행을 동일한 숫자로 공유하려면 rank() (또는 가능하면 dense_rank())을 사용하십시오. account에서 NULL 값이 할 수있는 경우에만

, 당신은 정렬 순서를 내림차순 NULLS LAST를 추가해야하거나 NULL 값 종류에 최고 :

은 동시 쓰기가있을 경우 위 쿼리는 경쟁 조건의 영향을받습니다. 고려 :

그러나,이 경우, 전체 개념 인 경우 하드 코딩 상위 10로 시작하는 반신 반의하는 방법이 될 것입니다.

1

확실히, 하위 쿼리에서 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에 대해 같은 값을 가지고 있다면, 그들은 같은 순위를 얻을 것이라는 특질이있다. 다음과 같은 기능을 고려해 볼 수 있습니다. :-)

관련 문제