2015-05-07 28 views
4

我有一個表t具有下列數據:分區中的窗口函數中的PostgreSQL錯誤?

name | n 
------------+--- 
school  | 4 
hotel  | 2 
restaurant | 6 
school  | 3 
school  | 5 
hotel  | 1 

當我運行下面的查詢,結果是有些奇怪。

select name, n, 
     first_value(n) over (partition by name order by n desc), 
     last_value(n) over (partition by name order by n) 
from t; 

    name | n | first_value | last_value 
------------+---+-------------+------------ 
hotel  | 1 |   2 |   1 
hotel  | 2 |   2 |   2 
restaurant | 6 |   6 |   6 
school  | 3 |   5 |   3 
school  | 4 |   5 |   4 
school  | 5 |   5 |   5 
(6 rows) 

雖然first_value作品如我所料,last_value工程奇怪。我認爲last_value列的值應該與first_value的值相同,因爲first_value是按n降序排列的。

這是PostgreSQL的bug還是我錯過了什麼?

的PostgreSQL的版本是:

postgres=# select version(); 
                   version 
----------------------------------------------------------------------------------------------------------------------------------- 
PostgreSQL 9.4.1 on x86_64-apple-darwin14.1.0, compiled by Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn), 64-bit 
(1 row) 

回答

9

不,這是不是一個錯誤。 first_value()last_value()函數在窗口框架上工作,而不是分區。如果沒有指定frame_clause,根據documentation,窗口框架默認爲分區開始到當前行。這正是您需要什麼first_value()last_value()你應該添加range between unbounded preceding and unbounded followingWINDOW定義看當前行超越:也

select name, n, 
     first_value(n) over (partition by name order by n desc), 
     last_value(n) over (partition by name order by n 
     range between unbounded preceding and unbounded following) 
from t; 

注意,這已經無關的分區中的行進行排序。該排序以某種順序生成分區(並不令人意外),然後基於框架的功能在窗口框架上工作,而不需要知道或關心任何行的排序。

+0

非常感謝。這是我在數據庫中見過的最瘋狂的api設計之一。如果我可以使用引用分區的'MAX'函數,然後用另一個函數替換,我希望它也可以在分區上工作。這只是理智。 當然,爲了向後兼容,他們現在需要保持這種愚蠢的態度,但是我們可以有一些預期的交替命名函數嗎? – Adamantish