window 分区函数中的 PostgreSQL 错误?

PostgreSQL bug in window function on partition?

我有一个 table t 具有以下数据:

    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 的错误还是我遗漏了什么?

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)

不,这不是错误。 first_value()last_value() 函数在 window 框架 上工作,而不是分区。如果未指定 frame_clause,则 window 框架与 documentation 一致,默认为当前行的分区起点。这正是 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;

另请注意,这与分区中行的排序无关。排序以特定顺序生成分区(不足为奇),然后基于框架的函数在 window 框架上工作,而不知道或不关心行的任何排序。