SQL查询求助:GROUP BY前ORDER BY关联表报错,需获取用户最新消息
解决获取指定用户最新消息的SQL问题
哥们,我来帮你搞定这个问题!先说说你为啥会报错:你修改后的查询里,子查询只选了mTIME并命名成M,但外层查询还在直接用messages.mCONV_NUM——这时候外层根本没把messages表拉进来啊,MySQL当然找不到这个表,所以才会报Table 'messages' unknown的错。
接下来给你两种靠谱的解决方案,根据你的MySQL版本选就行:
方案一:子查询获取每个对话的最新时间(兼容所有MySQL版本)
这个思路是先找出用户2参与的每个对话对应的最新消息时间,再关联回messages表拿到完整的消息记录,最后关联conversations表:
SELECT m.*, c.* FROM messages m JOIN ( -- 先获取每个对话的最新消息时间 SELECT mCONV_NUM, MAX(mTIME) AS latest_time FROM messages -- 只筛选用户2参与的对话 WHERE mCONV_NUM IN (SELECT cNUM FROM conversations WHERE cUSER2 = '2') GROUP BY mCONV_NUM ) AS latest_msg ON m.mCONV_NUM = latest_msg.mCONV_NUM AND m.mTIME = latest_msg.latest_time JOIN conversations c ON c.cNUM = m.mCONV_NUM WHERE c.cUSER2 = '2';
方案二:用窗口函数(MySQL 8.0+版本推荐)
如果你的MySQL是8.0及以上版本,用窗口函数会更简洁直观,直接按对话分组后给消息按时间排序,取每组的第一条就是最新消息:
SELECT * FROM ( SELECT m.*, c.*, -- 按对话分组,按时间倒序排名,每组第一条就是最新的 ROW_NUMBER() OVER (PARTITION BY m.mCONV_NUM ORDER BY m.mTIME DESC) AS rn FROM messages m JOIN conversations c ON c.cNUM = m.mCONV_NUM WHERE c.cUSER2 = '2' ) AS msg_with_rn WHERE rn = 1;
再补充下你最初的问题:为啥直接用GROUP BY拿不到最新消息?因为MySQL的GROUP BY是先分组再取第一条记录,而这个第一条记录不一定是时间最新的,必须先锁定每个对话的最新时间,再关联获取对应记录才行。
内容的提问来源于stack exchange,提问作者TiboK
相关产品推荐
相关产品推荐

