如何从MySQL获取指定Job下每个用户ID的最后一条唯一记录
解决MySQL中获取每个用户最后一条唯一记录的问题
我来帮你搞定这个需求——获取每个user_id对应的最后一条申请记录,你的原查询确实存在逻辑问题,导致无法返回预期结果,下面我拆解问题并给出几种靠谱的解决方案:
原查询的问题分析
你的原SQL:
SELECT LOWER(applied.job_status), applied.* FROM `jh_job_posting` as `job` JOIN `jh_job_applied` as `applied` ON `applied`.`applied_job_id` = `job`.`job_id` WHERE `job`.`job_id` = '41' GROUP BY applied.user_id ORDER by applied.user_id DESC
存在两个核心问题:
- 使用
GROUP BY applied.user_id但未指定聚合逻辑,MySQL在非严格模式下会返回组内随机一行,而非你需要的最后一条记录 - 仅对
user_id降序排序,没有控制每个用户内部记录的先后顺序,无法锁定"最后一条"
解决方案
方案1:使用窗口函数(MySQL 8.0+ 推荐)
窗口函数ROW_NUMBER()可以精准给每个用户的记录排序,直接筛选出每个用户的最后一条记录:
SELECT LOWER(applied_inner.job_status), applied_inner.* FROM ( SELECT ja.*, -- 按user_id分组,每组内按applied_id(自增主键)降序编号,最新记录编号为1 ROW_NUMBER() OVER (PARTITION BY ja.user_id ORDER BY ja.applied_id DESC) AS row_rank FROM `jh_job_applied` ja WHERE ja.applied_job_id = '41' ) AS applied_inner JOIN `jh_job_posting` jp ON applied_inner.applied_job_id = jp.job_id WHERE applied_inner.row_rank = 1 ORDER BY applied_inner.user_id DESC;
提示:如果表中有
created_at(创建时间)字段,用ORDER BY ja.created_at DESC代替applied_id会更贴合"最后一条"的业务逻辑。
方案2:关联子查询(兼容MySQL 5.x版本)
如果你的MySQL版本不支持窗口函数,用子查询先获取每个用户的最后一条记录ID,再关联原表取完整数据:
SELECT LOWER(ja.job_status), ja.* FROM `jh_job_applied` ja JOIN `jh_job_posting` jp ON ja.applied_job_id = jp.job_id WHERE jp.job_id = '41' AND ja.applied_id = ( -- 子查询获取当前user_id在job_id=41下的最大applied_id(即最后一条记录) SELECT MAX(applied_id) FROM `jh_job_applied` WHERE user_id = ja.user_id AND applied_job_id = '41' ) ORDER BY ja.user_id DESC;
方案3:MAX()聚合+JOIN组合
先分组获取每个用户的最后一条记录ID,再通过JOIN匹配完整数据:
SELECT LOWER(ja.job_status), ja.* FROM `jh_job_applied` ja JOIN ( -- 分组获取每个user_id的最新applied_id SELECT user_id, MAX(applied_id) AS latest_applied_id FROM `jh_job_applied` WHERE applied_job_id = '41' GROUP BY user_id ) AS latest_records ON ja.user_id = latest_records.user_id AND ja.applied_id = latest_records.latest_applied_id JOIN `jh_job_posting` jp ON ja.applied_job_id = jp.job_id WHERE jp.job_id = '41' ORDER BY ja.user_id DESC;
注意事项
- 确保用来判断"最后一条"的字段(如
applied_id、created_at)是单调递增的,能准确反映记录的生成顺序 - 如果业务中"最后一条"的定义不是按ID或时间,需要调整排序字段来匹配实际需求
内容的提问来源于stack exchange,提问作者Anoop P S
相关产品推荐
相关产品推荐

