只选择username = x的所有结果中的最新记录?

时间:2017-06-21 21:38:03

标签: mysql sql select

我目前正在尝试为我的网站创建某种形式的即时消息,允许用户彼此通信。为此,我创建了一个名为messages的sql表,标题为id, senderID, recipientID, timestamp, message

目前,我正在努力研究如何为id = x的给定用户创建所有对话(而不是单个消息)的列表。此列表应仅包含发送给用户x的最新消息,来自每个发件人y1,y2,y3,......

例如,考虑表

 -------------------------------------------------------------
|  ID  |  senderID  |  recipientID  |  timestamp  |  message  |
 -------------------------------------------------------------
|  1   |     14     |      34       | 2017-06-21  | Hello ... |
|  2   |     14     |      37       | 2017-06-22  | How ar... |
|  3   |     11     |      34       | 2017-06-23  | I was ... |
|  4   |     17     |      34       | 2017-06-24  | Good  ... |
|  5   |     18     |      34       | 2017-06-25  | My na ... |
|  6   |     11     |      34       | 2017-06-26  | I've  ... |
|  7   |     14     |      34       | 2017-06-27  | Thank ... |
|  8   |     12     |      34       | 2017-06-28  | I nee ... |
|  9   |     17     |      34       | 2017-06-29  | Have  ... |
|  10  |     17     |      34       | 2017-06-30  | You h ... |
 -------------------------------------------------------------

现在,假设我是用户34,我希望查看包含每个senderID给我自己的最新消息的列表。执行此操作的SQL查询是什么?即SQL查询会产生以下结果:

 -------------------------------------------------------------
|  ID  |  senderID  |  recipientID  |  timestamp  |  message  |
 -------------------------------------------------------------
|  5   |     18     |      34       | 2017-06-25  | My na ... |
|  6   |     11     |      34       | 2017-06-26  | I've  ... |
|  7   |     14     |      34       | 2017-06-27  | Thank ... |
|  8   |     12     |      34       | 2017-06-28  | I nee ... |
|  10  |     17     |      34       | 2017-06-30  | You h ... |
 -------------------------------------------------------------

使用哪些SQL命令来提供此结果?

4 个答案:

答案 0 :(得分:0)

这是一种方法:

select m.*
from messages m
where m.recipientId = 34 and
      m.timestamp = (select max(m2.timestamp)
                     from messages m2
                     where m2.senderId = m.senderId and m2.recipientId = m.recipientId
                    );

INEXISTSJOIN / GROUP BY都会做类似的事情。

答案 1 :(得分:0)

SELECT * FROM messages WHERE recipientId = 34 ORDER BY timestamp DESC;

答案 2 :(得分:0)

这是我的回答:

  1. 创建一个名为messages_latest的表,其列与表messages相同;
  2. 当有id = 1的用户向id = 34用户发送消息时,请先从表messages_latest senderID = 1recipientId = 34删除消息,然后插入最新消息记录到messages_latest;
  3. message_latest保存最新的消息。

答案 3 :(得分:0)

您可以创建第二个查询,以便MAX(timestamp)recipientID获取senderID组,然后只需加入messages表格,然后ORDER BY timestamp ASC

这样,您只会过滤senderID子句中从每个recipientID发送到指定WHERE的最后一条消息。

select m.*
from messages as m
  join ( select recipientID, senderID, max(timestamp) as timestamp
         from messages
         group by recipientID, senderID ) as l
  on m.recipientID = l.recipientID
    and m.senderID = l.senderID         
    and m.timestamp = l.timestamp
where m.recipientID = 34
order by m.timestamp asc

你可以在这里找到一个有用的SqlFiddle http://www.sqlfiddle.com/#!9/63a42/18