【问题标题】:PostgreSQL bug in window function on partition?分区窗口函数中的 PostgreSQL 错误?
【发布时间】:2015-05-07 04:08:32
【问题描述】:

我有一个表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)

【问题讨论】:

    标签: sql postgresql postgresql-9.4


    【解决方案1】:

    不,这不是错误。 first_value()last_value() 函数适用于窗口框架,而不是分区。如果没有指定frame_clause,则窗口框架,根据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;
    

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

    【讨论】:

    • 非常感谢。这是我在数据库中见过的最疯狂的 api 设计之一。如果我可以使用引用分区的MAX 函数,然后用另一个函数替换,我希望它也可以在分区上工作。这只是理智。当然,他们现在需要保持这种愚蠢以实现向后兼容性,但是我们可以有一些替代命名的函数来达到预期的效果吗?
    猜你喜欢
    • 2014-04-26
    • 1970-01-01
    • 2018-12-15
    • 2023-03-06
    • 2017-03-27
    • 2018-12-08
    • 2016-09-02
    • 2014-05-27
    • 2016-06-01
    相关资源
    最近更新 更多