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 按聚合函数分组的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB聚合使用表达式运算符(函数)分组按条件计数统计案例一则