如何在关联查询中仅获取有限结果?每个项目仅关联最新版本
这问题我太熟了!要拿到每个项目的最新版本同时保留所有列,确实没法用DISTINCT搞定,我给你几个靠谱的实战方案,都是日常工作里常用的:
方案1:窗口函数(推荐,适合现代数据库)
如果你的数据库支持窗口函数(比如MySQL 8+、PostgreSQL、SQL Server等),这是最直观高效的写法。核心思路是给每个项目的版本按创建时间倒序排号,取排号为1的那条就是最新版本:
SELECT p.id, p.name, p.owner_id, v.id AS version_id, v.tag, v.created_at FROM projects p JOIN ( SELECT *, -- 按项目分组,每个组内按创建时间倒序给版本排号 ROW_NUMBER() OVER (PARTITION BY project_id ORDER BY created_at DESC) AS rn FROM versions ) v ON p.id = v.project_id WHERE v.rn = 1;
小提示:如果存在多个版本在同一时间创建(created_at完全相同),ROW_NUMBER()会随机选一个;要是想保留所有同时间的最新版本,把ROW_NUMBER()换成RANK()即可。
方案2:子查询关联最大创建时间(兼容老版本数据库)
如果你的数据库不支持窗口函数(比如MySQL 5.x),可以先找出每个项目的最新创建时间,再通过这个时间关联到对应的版本:
SELECT p.id, p.name, p.owner_id, v.id AS version_id, v.tag, v.created_at FROM projects p JOIN versions v ON p.id = v.project_id JOIN ( -- 先拿到每个项目的最新创建时间 SELECT project_id, MAX(created_at) AS latest_created FROM versions GROUP BY project_id ) latest_v ON v.project_id = latest_v.project_id AND v.created_at = latest_v.latest_created;
这个写法会返回所有符合“最新创建时间”的版本,同样能处理多版本同时间的场景。
方案3:用NOT EXISTS筛选无更新版本
还有一种更“直白”的写法:找出那些没有比它更新的同项目版本的记录,也就是最新版本:
SELECT p.id, p.name, p.owner_id, v.id AS version_id, v.tag, v.created_at FROM projects p JOIN versions v ON p.id = v.project_id WHERE NOT EXISTS ( -- 如果找不到同项目里创建时间更晚的版本,说明当前v是最新的 SELECT 1 FROM versions v2 WHERE v2.project_id = v.project_id AND v2.created_at > v.created_at );
三种方案各有适用场景,优先推荐窗口函数,代码简洁且性能稳定;老数据库环境选方案2;方案3逻辑直观,适合理解基础关联逻辑。
内容的提问来源于stack exchange,提问作者helmet91
相关产品推荐
相关产品推荐

