我目前正在尝试为我的网站创建某种形式的即时消息,允许用户彼此通信。为此,我创建了一个名为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命令来提供此结果?
答案 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
);
IN
,EXISTS
和JOIN
/ GROUP BY
都会做类似的事情。
答案 1 :(得分:0)
SELECT * FROM messages WHERE recipientId = 34 ORDER BY timestamp DESC;
答案 2 :(得分:0)
这是我的回答:
messages_latest
的表,其列与表messages
相同; id = 1
的用户向id = 34
用户发送消息时,请先从表messages_latest
senderID = 1
和recipientId = 34
删除消息,然后插入最新消息记录到messages_latest
; 表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