【问题标题】:PostgreSQL aggregate or window function to return just the last valuePostgreSQL 聚合或窗口函数仅返回最后一个值
【发布时间】:2012-01-09 08:55:10
【问题描述】:

我在 PostgreSQL 9.1 中使用带有 OVER 子句的聚合函数,我想只返回每个窗口的最后一行。 last_value() 窗口函数听起来好像它可以做我想做的事——但事实并非如此。它为窗口中的每一行返回一行,而我只希望每个窗口一行

一个简化的例子:

SELECT a, some_func_like_last_value(b) OVER (PARTITION BY a ORDER BY b)
FROM
(
    SELECT 1 AS a, 'do not want this' AS b
    UNION SELECT 1, 'just want this'
) sub

我希望它返回一行:

1, 'just want this'

【问题讨论】:

    标签: sql postgresql aggregate-functions


    【解决方案1】:

    DISTINCT加窗口功能

    添加DISTINCT 子句:

    SELECT DISTINCT a
         , last_value(b) OVER (PARTITION BY a ORDER BY b
                               RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
    FROM  (
       VALUES
         (1, 'do not want this')
        ,(1, 'just want this')
       ) sub(a, b);
    

    更多关于DISTINCT

    DISTINCT ON 更简单、更快捷

    PostgreSQL 也有这个 SQL 标准的扩展:

    SELECT DISTINCT ON (a)
           a, b
    FROM  (
       VALUES
         (1, 'do not want this')
       , (1, 'just want this')
       ) sub(a, b)
    ORDER  BY a, b DESC;
    

    更多关于DISTINCT ON 和可能更快的替代方案:

    简单聚合的简单案例

    如果您的案例实际上与您的演示一样简单(并且您不需要最后一行的其他列),那么简单的聚合函数会更简单:

    SELECT a, max(b)
    FROM  (
       VALUES
         (1, 'do not want this')
       , (1, 'just want this')
       ) sub(a, b)
    GROUP  BY a;
    

    【讨论】:

    • 谢谢。它实际上返回了第一行('不想要这个'),但添加 RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING 似乎可以解决它。
    • @EMP:对了,我忘了这个。根据您的反馈修改了我的回答。
    • @EMP:我用更好的解决方案更新了答案。你可能会感兴趣。
    【解决方案2】:

    虽然问题已得到解答,但我想为遇到此类问题的人提供简单的说明。 如果您在两个不同的列上使用“Partition by”和“Order by”,则必须在“Order By”之后使用窗口函数内的框架以获得所需的结果。

    More information here.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-16
      • 2014-05-29
      • 1970-01-01
      • 2017-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多