sql - SQL中如何获取某个用户每次对话的最新消息?

标签 sql postgresql greatest-n-per-group

我需要编写一个查询,返回两个用户对话中的最新消息。我在这个 fiddle 中包含了模式和我的(失败的)尝试:http://sqlfiddle.com/#!15/322c3/11

我已经解决这个问题一段时间了,但每次我运行任何丑陋的查询时,都会有一只可爱的小猫死去

任何帮助将不胜感激。为小猫做。

最佳答案

... the latest message in a conversation between two users.

假设 ID 为 13 的用户,就像您在 fiddle 中所做的那样,我们对具有最新 created_at 的消息感兴趣和 (sender_id, receiver_id)(1,3)(3,1)

您可以使用临时行类型来缩短语法:

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 的详细解释:

sqlfiddle - 改进和简化的测试用例

关于sql - SQL中如何获取某个用户每次对话的最新消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20856416/

相关文章:

c# - 如何删除另一表中包含其父行的数据的行

Postgresql 链接服务器查询非常慢

postgresql - 仔细检查 PostgreSQL 服务器上的夏令时规则是否最新?

sql - 每个标准的限制

mysql - 合并数据,特定条件下除外

mysql - 计算通过左外连接连接的两个表

c# - 如何使用 Dapper 高效地选择聚合对象?

postgresql - 如何对 PostgreSQL 数据库运行 MDX 查询?

hive - 显示每组最大值的配置单元表

sql - T-SQL : How to select rows based on the max date?