我正在两个用户之间建立一个聊天系统。我有一张这样的聊天桌:(这是schema:sql fiddle)
--------------------------------------------------------------------------------
| message_id | sender_id | receiver_id | message_text | date |
--------------------------------------------------------------------------------
| 1 | 20 | 100 | Hello mate | 2018-04-29 12:15:33 |
--------------------------------------------------------------------------------
| 2 | 100 | 20 | Hi there | 2018-04-29 13:20:05 |
--------------------------------------------------------------------------------
| 3 | 13 | 44 | Alright | 2018-04-29 14:35:15 |
--------------------------------------------------------------------------------
| 4 | 20 | 57 | Hi user 57 | 2018-04-29 16:44:34 |
--------------------------------------------------------------------------------
我想从用户参与的每个聊天中获取最后一条消息的行,因此在上面的示例中,用户20应该获得2行:消息行\u id 2(因为他参与了与用户100的聊天,尽管他没有发送最后一条消息),第4行消息(因为他向用户57发送了消息)基本上就像whatsapp,在上面总是有任何聊天的第一条消息。
问题是,如果用户是发送者,而不是接收者,我只能获得最后一条消息:
SELECT * FROM chat
WHERE message_id IN
(SELECT MAX(message_id) FROM chat WHERE sender_id=:sender_id
GROUP BY receiver_id) ORDER BY date DESC
我想我应该添加另一个列“chat\u id”,这将是一个数字,对于处于同一个chat中的每2个用户都是相同的(因此用户100和20将具有相同的chat\u id,无论他们是发送者还是接收者,在这个示例中,用户13和44将具有不同的chat\u id),
或者,有更好的选择吗?
2条答案
按热度按时间mkshixfv1#
要有效地处理此问题,请从以下两个查询开始:
可以使用两个索引对每个索引进行优化:
messages(receiver_id, sender_id, message_id)
以及messages(sender_id, receiver_id, message_id)
.你可以
union all
将它们放在一起并进行排序或聚合以获得最大值:子查询应该能够使用索引(实际上,不需要“otherid”)。这个
max()
然后在两排in
应该能够利用上的索引(message_id)
.编辑:
对于修改后的问题,我想不出一个真正有效的方法。这里有一种方法:
qgelzfjb2#
您可以使用发送方和接收方之间的联合来获得两者的结果