MySQL:获取满足特定条件的最新记录(复杂场景)
看起来你需要针对每个id提取它的最新记录(按created时间排序)对吧?结合你给出的表结构和数据,我整理了两种实用的解决方案,分别适配不同版本的MySQL:
方案1:使用窗口函数(MySQL 8.0+推荐)
窗口函数是处理这类分组取最新/最早记录最简洁的方式,用ROW_NUMBER()按id分组,再按created降序排序,取每组的第一条即可:
SELECT id, rating, created FROM ( SELECT id, rating, created, ROW_NUMBER() OVER (PARTITION BY id ORDER BY created DESC) AS rn FROM test_table ) t WHERE rn = 1;
逻辑说明:
PARTITION BY id:把相同id的记录归为一组ORDER BY created DESC:每组内按创建时间倒序排列,最新的记录会排在第1位- 外层筛选
rn=1,就能精准拿到每个id的最新记录
如果你的业务场景中,同一个id可能存在多条创建时间完全相同的最新记录,想要保留所有这些记录的话,可以把ROW_NUMBER()换成RANK()或者DENSE_RANK()——这两个函数会给相同时间的记录分配相同的排名,最终所有符合条件的记录都会被筛选出来。
方案2:兼容低版本MySQL(无窗口函数)
如果你的MySQL版本低于8.0,不支持窗口函数,可以用子查询先获取每个id的最大created时间,再关联原表拿到对应记录:
SELECT t1.id, t1.rating, t1.created FROM test_table t1 INNER JOIN ( SELECT id, MAX(created) AS latest_created FROM test_table GROUP BY id ) t2 ON t1.id = t2.id AND t1.created = t2.latest_created;
逻辑说明:
- 子查询
t2先计算出每个id对应的最晚创建时间 - 通过
id和created字段关联原表t1,就能匹配到每个id最新时间对应的完整记录
同样,如果同一个id有多个相同的最新时间记录,这个查询会返回所有符合的记录;如果只需要其中一条,可以结合LIMIT和分组逻辑,但这种情况更推荐用方案1,灵活性更高。
额外需求适配:如果要取最新的非NULL rating记录
如果你实际需要的不是每个id的任意最新记录,而是最新的带有有效评分(rating不为NULL)的记录,只需要给查询加个过滤条件即可:
方案1调整后:
SELECT id, rating, created FROM ( SELECT id, rating, created, ROW_NUMBER() OVER (PARTITION BY id ORDER BY created DESC) AS rn FROM test_table WHERE rating IS NOT NULL ) t WHERE rn = 1;
方案2调整后:
SELECT t1.id, t1.rating, t1.created FROM test_table t1 INNER JOIN ( SELECT id, MAX(created) AS latest_created FROM test_table WHERE rating IS NOT NULL GROUP BY id ) t2 ON t1.id = t2.id AND t1.created = t2.latest_created;
你可以根据自己的实际业务需求选择对应的写法~
内容的提问来源于stack exchange,提问作者Yueleng
相关产品推荐
相关产品推荐

