SQL分组ID去重遇1055报错且无权限修改sql_mode求解决
原SQL的核心问题
- GROUP BY 目标错误:你写的
GROUP BY receiverID毫无意义——WHERE receiverID = :senderID已经限定所有结果的接收者都是当前用户,分组后只会返回一行,完全达不到“相同联系人ID去重”的目的,你应该按senderID(对方用户ID)分组。 - SELECT * 违反SQL模式规则:在
only_full_group_by模式下,SELECT列表中的列要么出现在GROUP BY中,要么用聚合函数(如MAX、MIN)包裹,否则MySQL无法确定要返回分组内哪一行的非聚合列值,直接触发报错。
由于你没有SUPER权限修改sql_mode,直接调整SQL语句是唯一可行方案,以下是两种适配需求的写法:
方案1:仅获取去重的联系人基本信息
如果只需要对方的用户信息(不需要聊天内容),用DISTINCT即可实现去重,同时按消息时间排序:
SELECT DISTINCT ui.userID, ui.username, ul.email -- 按需选择需要的列,避免用* FROM chat INNER JOIN user_info ui ON ui.userID = chat.senderID INNER JOIN user_login ul ON ul.userID = chat.senderID WHERE chat.receiverID = :senderID ORDER BY (SELECT MIN(messageID) FROM chat WHERE senderID = ui.userID AND receiverID = :senderID) ASC
方案2:获取每个联系人的第一条消息+用户信息
如果需要同时展示每个联系人的某条消息(比如最早发送的那条),用子查询先锁定每个联系人对应的消息ID,再关联查询:
SELECT ui.userID, ui.username, ul.email, c.message, c.messageID, c.sendTime FROM ( -- 分组获取每个联系人的最早消息ID SELECT senderID, MIN(messageID) AS target_msg_id FROM chat WHERE receiverID = :senderID GROUP BY senderID ) AS sub -- 通过消息ID关联回chat表,拿到对应消息内容 INNER JOIN chat c ON c.senderID = sub.senderID AND c.messageID = sub.target_msg_id INNER JOIN user_info ui ON ui.userID = c.senderID INNER JOIN user_login ul ON ul.userID = c.senderID -- 按消息ID升序排序 ORDER BY c.messageID ASC
如果想展示最新消息,只需把MIN(messageID)换成MAX(messageID),排序也可改为ORDER BY c.messageID DESC。
内容的提问来源于stack exchange,提问作者Caleby
相关产品推荐
相关产品推荐

