我有一个消息表,如下所示:
+------------+-------------+----------+
| 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对应的消息。
有没有办法解决这个问题,或者我是以错误的方式接近它?
答案 0 :(得分:7)
此:
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)
上创建一个索引,以便快速工作。
您可能会发现这篇文章很有趣:
答案 1 :(得分:1)
使用相关的子查询:
select * from messages m1
where m1.created_at = (
select max(m2.create_at)
from messages m2
where m1.sender_id = m2.sender_id
);
对上层查询处理的每一行重新评估子查询。
答案 2 :(得分:0)
使用distinct on:
SELECT DISTINCT ON (sender_id)
sender_id,created_at,message
FROM messages
ORDER BY sender_id,created_at DESC