SQL如何查询每个ID对应最新日期(当日)的calc_score记录
每个ID对应最新分数查询最优实现方案
以下方案按适用场景和性能排序:
PostgreSQL专属最优写法(你提到的DISTINCT ON正确用法)
之前用DISTINCT ON没得到正确结果大概率是排序规则配置错误,DISTINCT ON必须和ORDER BY搭配,将分组字段放在排序最前面,再按日期倒序就能直接取到每个id的最新记录,性能比窗口函数、子查询写法都高:
SELECT DISTINCT ON (id) id, calc_score, date FROM your_table ORDER BY id, date DESC;
全数据库通用写法(支持MySQL、SQL Server、Oracle等所有关系型数据库)
用ROW_NUMBER窗口函数实现,逻辑清晰兼容性最好:
WITH ranked_score AS ( SELECT id, calc_score, date, ROW_NUMBER() OVER(PARTITION BY id ORDER BY date DESC) AS rn FROM your_table ) SELECT id, calc_score, date FROM ranked_score WHERE rn = 1;
如果是不支持CTE的低版本数据库,可改写成子查询形式:
SELECT id, calc_score, date FROM ( SELECT id, calc_score, date, ROW_NUMBER() OVER(PARTITION BY id ORDER BY date DESC) AS rn FROM your_table ) t WHERE rn = 1;
简易关联查询写法
如果不需要保留日期字段、或数据库版本过老不支持窗口函数,可以用分组关联写法,性能略低于窗口函数方案:
SELECT t1.id, t1.calc_score FROM your_table t1 INNER JOIN ( SELECT id, MAX(date) AS latest_date FROM your_table GROUP BY id ) t2 ON t1.id = t2.id AND t1.date = t2.latest_date;
常见注意点
- 若
date字段存储的是字符串类的非标日期值(如示例中的today/yesterday),需先转换为可正确排序的日期类型,否则排序逻辑错误会直接导致返回结果不符合预期,这也是DISTINCT ON、窗口函数类写法最常见的踩坑点。 - 若同一个id同一天存在多条计算记录,可在排序规则后追加主键/生成时间倒序,比如修改排序逻辑为
ORDER BY id, date DESC, record_id DESC,即可取到当日最新生成的那条记录。
内容的提问来源于stack exchange,提问作者Eddy
相关产品推荐
相关产品推荐

