You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MySQL从数据表获取唯一数据:获取用户A与好友的最新消息

获取用户A与所有好友的最后一条消息

我来帮你搞定这个需求!首先得明确几个前提:你没给出message表的结构,我先按常见的消息表设计假设它包含sender(发送者ID)、receiver(接收者ID)、content(消息内容)、send_time(发送时间)这些核心字段。另外friend表的pending字段如果是用来标记好友请求是否通过的,我会在查询里默认只筛选已通过的好友(假设pending = 0代表已通过,你可以根据实际值调整)。

方法一:使用窗口函数(推荐,逻辑清晰)

这种方法利用ROW_NUMBER()窗口函数对每个好友与A的消息按时间倒序排序,直接取第一条就是最新消息:

WITH user_a_friends AS (
    -- 先获取用户A的所有已通过好友
    SELECT 
        CASE 
            WHEN user1 = {userA_id} THEN user2 
            ELSE user1 
        END AS friend_id
    FROM friend
    WHERE (user1 = {userA_id} OR user2 = {userA_id})
      AND pending = 0 -- 筛选已通过的好友,可根据实际情况调整
),
friend_messages AS (
    -- 获取A与每个好友之间的所有消息
    SELECT 
        uf.friend_id,
        m.content,
        m.send_time,
        m.sender,
        m.receiver,
        -- 按好友分组,消息按时间倒序排名
        ROW_NUMBER() OVER (PARTITION BY uf.friend_id ORDER BY m.send_time DESC) AS rn
    FROM user_a_friends uf
    JOIN message m 
        ON (m.sender = {userA_id} AND m.receiver = uf.friend_id)
        OR (m.sender = uf.friend_id AND m.receiver = {userA_id})
)
-- 取每个好友的第一条(最新)消息
SELECT 
    friend_id,
    content AS last_message_content,
    send_time AS last_message_time,
    CASE WHEN sender = {userA_id} THEN '我发送的' ELSE '好友发送的' END AS message_direction
FROM friend_messages
WHERE rn = 1;

方法二:使用分组 + 子查询

如果你的数据库不支持窗口函数(比如老版本MySQL),可以用这种方式:

SELECT 
    -- 先确定好友ID
    CASE 
        WHEN f.user1 = {userA_id} THEN f.user2 
        ELSE f.user1 
    END AS friend_id,
    m.content AS last_message_content,
    m.send_time AS last_message_time,
    CASE WHEN m.sender = {userA_id} THEN '我发送的' ELSE '好友发送的' END AS message_direction
FROM friend f
JOIN message m 
    ON (m.sender = {userA_id} AND m.receiver = CASE WHEN f.user1 = {userA_id} THEN f.user2 ELSE f.user1 END)
    OR (m.sender = CASE WHEN f.user1 = {userA_id} THEN f.user2 ELSE f.user1 END AND m.receiver = {userA_id})
-- 关联子查询找到每个好友与A之间的最新消息时间
JOIN (
    SELECT 
        CASE 
            WHEN sender = {userA_id} THEN receiver 
            ELSE sender 
        END AS friend_id,
        MAX(send_time) AS latest_time
    FROM message
    WHERE sender = {userA_id} OR receiver = {userA_id}
    GROUP BY CASE WHEN sender = {userA_id} THEN receiver ELSE sender END
) latest_m 
    ON latest_m.friend_id = CASE WHEN f.user1 = {userA_id} THEN f.user2 ELSE f.user1 END
    AND m.send_time = latest_m.latest_time
WHERE (f.user1 = {userA_id} OR f.user2 = {userA_id})
  AND f.pending = 0;

关键说明

  • 把{userA_id}替换成实际的用户A的ID;
  • 如果pending字段不需要过滤(比如所有记录都是已通过好友),可以去掉AND pending = 0这个条件;
  • 如果你需要更多消息字段(比如消息ID),直接在SELECT里添加对应的字段即可。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:33:34