含子查询、GROUP BY与MAX的MySQL查询问题:获取最新关联记录
解决分组查询字段不匹配问题,获取每个receiverId+fromNumber组合的最后插入记录
问题根源
之前的分组查询仅能正确获取目标ID,是因为分组后直接选取非聚合字段时,数据库会随机返回该分组内的某条记录值,而非对应最大ID(最后插入)的那条记录的字段值。
解决方案(支持窗口函数的数据库:MySQL 8.0+/PostgreSQL/SQL Server等)
使用ROW_NUMBER()窗口函数,给每个receiverId+fromNumber组合的记录按插入顺序(ID或创建时间)排序,筛选出每个组内的第一条记录(即最后插入的那条):
SELECT m.id, m.receiverId, m.fromNumber, m.other_main_fields, -- 替换为实际主表需要的字段 msg.other_message_fields -- 替换为实际关联表需要的字段 FROM ( SELECT *, -- 按receiverId和fromNumber分组,组内按ID降序排序(大ID为后插入) ROW_NUMBER() OVER(PARTITION BY receiverId, fromNumber ORDER BY id DESC) AS rn -- 若有专门的创建时间字段,建议用 ORDER BY create_time DESC 更准确 FROM ctb_smsMessenger ) m -- 关联表,确保关联字段匹配(这里假设关联字段为messengerId,需根据实际调整) LEFT JOIN ctb_smsMessengerMessage msg ON m.id = msg.messengerId WHERE m.rn = 1 -- 取每个组合的最后插入记录 AND m.id IN (2, 11, 14, 19); -- 筛选目标ID
兼容MySQL 5.x的方案(无窗口函数支持)
通过子查询先获取每个receiverId+fromNumber组合的最大ID(最后插入记录的ID),再关联主表和关联表:
SELECT m.id, m.receiverId, m.fromNumber, m.other_main_fields, msg.other_message_fields FROM ctb_smsMessenger m LEFT JOIN ctb_smsMessengerMessage msg ON m.id = msg.messengerId -- 关联子查询,匹配每个组合的最大ID INNER JOIN ( SELECT receiverId, fromNumber, MAX(id) AS max_id FROM ctb_smsMessenger GROUP BY receiverId, fromNumber ) t ON m.receiverId = t.receiverId AND m.fromNumber = t.fromNumber AND m.id = t.max_id WHERE m.id IN (2, 11, 14, 19);
注意事项
- 替换SQL中的
other_main_fields、other_message_fields为实际需要查询的字段 - 确认关联表的关联字段(如示例中的
messengerId)与实际表结构一致 - 若依赖创建时间判断插入顺序,需将排序字段替换为对应的时间字段(如
create_time),子查询中则用MAX(create_time)
内容的提问来源于stack exchange,提问作者NME New Media Entertainment
相关产品推荐
相关产品推荐

