如何在不使用子查询的情况下为每个外键选取最新记录(SQL实现)
解决方案:获取每个foreign_key的最新记录(无SELECT子查询)
没问题,针对你的需求,这里有两种高效的实现方式,都不会在SELECT语句的字段中使用子查询,完全符合你的性能要求:
方法1:GROUP BY + JOIN(兼容多数数据库)
这种方法先通过分组得到每个foreign_key对应的最新created_at,再通过JOIN关联原表获取对应的string值:
SELECT f.foreign_key, f.string, f.created_at FROM files f JOIN ( SELECT foreign_key, MAX(created_at) AS max_created_at FROM files GROUP BY foreign_key ) AS latest ON f.foreign_key = latest.foreign_key AND f.created_at = latest.max_created_at;
说明:
- 子查询仅用于生成每个分组的最新时间,属于JOIN的数据源,并非SELECT字段中的子查询,满足你的限制条件
- 该方式兼容性强,几乎支持所有关系型数据库
方法2:窗口函数(适合支持SQL:2003及以上的数据库)
如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server等),这种方式代码更简洁,性能也很出色:
SELECT foreign_key, string, created_at FROM ( SELECT foreign_key, string, created_at, ROW_NUMBER() OVER(PARTITION BY foreign_key ORDER BY created_at DESC) AS rn FROM files ) AS ranked WHERE rn = 1;
说明:
- 这里的子查询是在FROM子句中生成带排名的中间结果,同样没有在SELECT字段中使用子查询
ROW_NUMBER()会按foreign_key分组,每组内按created_at倒序排名,取排名为1的记录就是该组的最新记录
两种方法都能得到你期望的结果:
| foreign_key | string | created_at |
|---|---|---|
| 1 | "a" | 2021-11-10 |
| 2 | "c" | 2021-11-18 |
内容的提问来源于stack exchange,提问作者Lukas Grofcik
相关产品推荐
相关产品推荐

