...两个用户之间的对话中的最新消息。
假设 ID 为 1 和 3 的用户,就像你在小提琴中所做的那样,我们对最新的 created_at 和 (sender_id, receiver_id) 是 (1,3) 或 (3,1) 的消息感兴趣。
您可以使用 ad-hoc 行类型来缩短语法:
SELECT *
FROM messages
WHERE (sender_id, receiver_id) IN ((1,3), (3,1))
ORDER BY created_at DESC
LIMIT 1;
或显式(并且速度稍快,也更容易与索引一起使用):
SELECT *
FROM messages
WHERE (sender_id = 1 AND receiver_id = 3 OR
sender_id = 3 AND receiver_id = 1)
ORDER BY created_at DESC
LIMIT 1;
对于用户的所有个会话
根据评论中的要求添加了解决方案。
SELECT DISTINCT ON (user_id) *
FROM (
SELECT 'out' AS type, id, receiver_id AS user_id, body, created_at
FROM messages
WHERE sender_id = 1
UNION ALL
SELECT 'in' AS type, id, sender_id AS user_id, body, created_at
FROM messages
WHERE receiver_id = 1
) sub
ORDER BY user_id, created_at DESC;
这里的做法是将外来的sender/receiver折叠成一列,以简化最后一行的提取。
在此相关答案中对DISTINCT ON的详细解释:
Select first row in each GROUP BY group?
-> Updated SQLfiddle.
还要考虑小提琴中改进和简化的测试用例。