重新排列聊天标签的顺序,使包含最新接收或发送的消息的标签位于列表顶部

问题描述

我正在开发一个简单的Messenger。

这是聊天表的外观:

enter image description here


这是User表的样子:

enter image description here


PinnedUser表的外观如下:

enter image description here


通过使用此查询,我可以显示与我固定的用户的聊天选项卡(固定到Messenger,以便我可以与他们聊天)。

SELECT pu.*,u.* FROM User u JOIN PinnedUser pu ON pu.pinned_user = u.user_id 
WHERE pu.pinned_by_user = $actual_user ORDER BY u.first_name ASC

聊天标签示例:

enter image description here

当我单击其中一个选项卡时,将显示与该用户的聊天消息。

现在,这些标签用户的名字排序(您可以在上面的查询中看到)。我需要做的是,我需要按最新消息对标签进行排序。

因此,如果“ Anet”向我发送消息(并且刷新页面,因为现在我不想使用AJAX进行操作),则该选项卡将显示在选项卡列表的顶部。然后,如果“演示”向我发送消息(并且刷新页面,因为现在我不想使用AJAX进行操作),则“演示”选项卡将位于顶部,而“ Anet”将位于其下方。因此,我需要按“最新接收或发送的消息”对标签进行排序,就像Facebook的Messenger中有标签一样。

我尝试用GROUP BY做魔术,但失败了。

解决方法

您需要检索每个用户最近收到的消息的日期-为此,我们需要查找表chat。您可以在where子句中加入或直接使用相关子查询:

select pu.*,u.* 
from user u 
join pinneduser pu on pu.pinned_user = u.user_id 
where u.user_id = ? 
order by (
    select coalesce(max(send_at),'200-01-01')
    from chat c
    where c.sender_id = pu.pinned_user_id and c.receiver_id = u.user_id
) desc

coalesce()可以在没有消息的情况下找到,在这种情况下,固定用户应排在最后(假设您在2k年之前没有消息)。

您可能还希望检索消息日期,以在应用程序中显示它(否则,我们不需要默认值):

select 
    pu.*,u.*,(
        select max(send_at)
        from chat c
        where c.sender_id = pu.pinned_user_id and c.receiver_id = u.user_id
    ) latest_message_sent_at
from user u 
join pinneduser pu on pu.pinned_user = u.user_id 
where u.user_id = ? 
order by (latest_message_sent_at is null),latest_message_sent_at desc