2011-04-04 33 views
26

如何在PostgreSQL中獲得某行的排序結果?PostgreSQL中的行編號

例如

SELECT 30+row_number() AS position, * 
FROM users 
ORDER BY salary DESC 
LIMIT 30 
OFFSET 30 

我假定查詢將這樣的返回列表:

position | name | salary 
31  | Joy | 4500 
32  | Katie| 4000 
33  | Frank| 3500 

其實我已經到ORDER條款複製到查詢,使之功能:

SELECT 30+row_number(ORDER BY salary DESC) AS position, * 
FROM users 
ORDER BY salary DESC 
LIMIT 30 
OFFSET 30 

有任何其他方式如何返回有序和編號的結果,而不必複製代碼?

我知道這可以通過增加的應用程序本身的一些變量來解決,但我想這樣做在數據庫層,並返回到已編號的結果應用...

回答

37

否 - order by的窗口函數和select語句的order by子句在功能上是兩個不同的東西。

此外,您的語句產生:ERROR: window function call requires an OVER clause,所以:

SELECT 30+row_number(ORDER BY salary DESC) AS position, * FROM users ORDER BY salary DESC LIMIT 30 OFFSET 30 

應該是:

SELECT 30+row_number() OVER(ORDER BY salary DESC) AS position, * FROM users ORDER BY salary DESC LIMIT 30 OFFSET 30 

注意,如果工資不是唯一的則沒有保證,他們甚至會產生相同的訂購。也許這將是更好的事情可做:

SELECT * 
FROM (SELECT 30+row_number() OVER(ORDER BY salary DESC) AS position, * 
     FROM users) 
ORDER BY position LIMIT 30 OFFSET 30 

還要注意的是,如果你正在運行此查詢幾次與不同的偏移量,您需要:

  1. 設置你的isolation level到序列化
  2. 確保無論您訂購的產品是否獨一無二

或者您可能會得到重複和缺少的行。請參閱有關this answer的評論。

+0

「隔離級別可重複讀」是所有必需的......但無論哪種方式,您都需要確保連接和事務保持打開狀態......根據應用程序的不同,這可能非常困難。 – 2016-05-02 21:30:46