postgres 按聚合函数分组

Posted

技术标签:

【中文标题】postgres 按聚合函数分组【英文标题】:postgres group by aggregate function 【发布时间】:2011-04-11 09:43:12 【问题描述】:

我有一个如下所示的消息表:

+------------+-------------+----------+
| sender_id  |  created_at | message  |
+------------+-------------+----------+
|      1     | 2010-06-14  | the msg  |
|      1     | 2010-06-15  | the msg  |
|      2     | 2010-06-16  | the msg  |
|      3     | 2010-06-14  | the msg  |
+------------+-------------+----------|

我想为每个发件人选择一条最近的消息。

这似乎是 GROUP BY sender_id 和 ORDER BY created_at,但我无法选择最近的消息。

我正在使用 postgres,因此如果我想按该字段排序,则需要在 SELECT 语句中的 created_at 字段上使用聚合函数,所以我正在考虑做这样的事情作为初始测试

SELECT messages.sender_id, MAX(messages.created_at) as the_date 
FROM messages 
GROUP BY sender_id 
ORDER BY the_date DESC 
LIMIT 10;

这似乎可行,但是当我也想选择“消息”时,我不知道要在其上使用什么聚合函数。我基本上只想要与 MAX created_at 对应的消息。

有什么方法可以解决这个问题还是我用错了方法?

【问题讨论】:

你是什么版本的? 【参考方案1】:

这个:

SELECT  *
FROM    (
        SELECT  DISTINCT ON (sender_id) *
        FROM    messages 
        ORDER BY
                sender_id, created_at DESC 
        ) q
ORDER BY
        created_at DESC
LIMIT 5

或者这个:

SELECT  (mi).*
FROM    (
        SELECT  (
                SELECT  mi
                FROM    messages mi
                WHERE   mi.sender_id = m.sender_id
                ORDER BY
                        created_at DESC
                LIMIT 1
                ) AS mi
        FROM    messages m
        GROUP BY
                sender_id
        ) q
ORDER BY
        (mi).created_at  DESC
LIMIT 5

(sender_id, created_at) 上创建一个索引以使其快速工作。

您可能会觉得这篇文章很有趣:

PostgreSQL: Selecting records holding group-wise maximum

【讨论】:

这一个给出了不同的结果,排序顺序不同。 @Frank:您可以将其用作子查询并使用上级查询重新排序结果。 @Frank:原问题没有提到sender_id上的顺序,但这里是更正顺序的查询。 关于这篇文章,我不能使用任何 8.4 的方法,比如我在 8.3 上的 windows 功能。您在那里给出的第二个查询给出了一个错误(“mi”处或附近的语法错误)。我需要按日期订购,所以也不能在那里使用 DISTINCT ON 的想法。 @johnnymire:查看帖子更新。至于第二个查询,它在哪一行给出错误?【参考方案2】:

使用相关子查询:

select * from messages m1 
where m1.created_at = (
    select max(m2.create_at) 
    from messages m2 
    where m1.sender_id = m2.sender_id
);

子查询为上层查询处理的每一行重新计算。

【讨论】:

【参考方案3】:

在不同的地方使用:

    SELECT DISTINCT ON (sender_id) 
           sender_id,created_at,message
      FROM messages
  ORDER BY sender_id,created_at DESC

【讨论】:

以上是关于postgres 按聚合函数分组的主要内容,如果未能解决你的问题,请参考以下文章

使用聚合函数但不想按特定列分组

Django 09-1模型层 查询(分组聚合)

django 中的聚合函数,分组函数,F 查询, Q查询

MongoDB聚合使用表达式运算符(函数)分组按条件计数统计案例一则

MongoDB聚合使用表达式运算符(函数)分组按条件计数统计案例一则

如何在 pyspark 中对需要在聚合中聚合的分组数据应用窗口函数?