PostgreSQL聚合或窗口函数只返回最后一个值

时间:2011-11-30 02:55:04

标签: sql postgresql aggregate-functions

我在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'

2 个答案:

答案 0 :(得分:14)

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;

答案 1 :(得分:0)

虽然这个问题已经回答了,但我还是想让有这样问题的人简单一些。 如果您在两个不同的列上使用 'Partition by' 和 'Order by',那么您必须在 'Order By' 之后使用窗口函数内的框架来获得所需的结果。

More information here.