分区窗口函数中的PostgreSQL错误?

nta*_*lbs 6 sql postgresql postgresql-9.4

我有一个t包含以下数据的表:

    name    | n
------------+---
 school     | 4
 hotel      | 2
 restaurant | 6
 school     | 3
 school     | 5
 hotel      | 1
Run Code Online (Sandbox Code Playgroud)

当我运行以下查询时,结果有点奇怪.

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)
Run Code Online (Sandbox Code Playgroud)

虽然first_value按照我的预期last_value工作,但很奇怪.我认为last_value列的值应该与first_value's 相同,因为它first_value是按n降序排序的.

这是PostgreSQL的错误还是我错过了什么?

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)
Run Code Online (Sandbox Code Playgroud)

Pat*_*ick 11

不,这不是一个错误.在first_value()last_value()所述上工作的功能窗框,而不是分区.根据文档,窗口框架默认为分区的开始,如果未frame_clause指定,则为当前行.这正是您所需要的,first_value()但是last_value()您应该添加range between unbounded preceding and unbounded following到您的WINDOW定义中以超越当前行:

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;
Run Code Online (Sandbox Code Playgroud)

另请注意,这与分区中行的排序无关.排序以特定顺序(不出意料地)生成分区,然后基于帧的函数在窗口框架上工作,而不知道或关心行的任何排序.