Oracle如何按ID分组后取每个分组内VERSION最大的第一行数据
实现方案
下面是不同场景下的实现方式:
1. 窗口函数法(主流数据库通用,支持 MySQL 8.0+、PostgreSQL、Oracle、SQL Server 等)
这是目前最推荐的写法,逻辑清晰性能好:
WITH ranked_t AS ( SELECT *, -- 相同ID为一组,组内按VERSION倒序排序生成行号 ROW_NUMBER() OVER(PARTITION BY ID ORDER BY VERSION DESC) AS rn FROM t ) -- 只取每组行号为1的,就是对应ID版本最高的行 SELECT ID, VERSION /* 补充需要的其他字段即可 */ FROM ranked_t WHERE rn = 1;
如果同一个ID存在多条相同最大VERSION的记录,需要全部保留的话,把ROW_NUMBER()替换为RANK()即可。
2. 分组关联法(兼容低版本数据库,比如 MySQL 5.x 等不支持窗口函数的环境)
先分组查询出每个ID对应的最大版本号,再关联回原表取完整行数据:
SELECT t.* FROM t INNER JOIN ( -- 先取每个ID的最大版本号 SELECT ID, MAX(VERSION) AS max_ver FROM t GROUP BY ID ) t_max ON t.ID = t_max.ID AND t.VERSION = t_max.max_ver;
注意:如果同一个ID存在多条相同最大VERSION的记录,这个写法会返回所有符合条件的记录。
3. 数据库专属简化写法
部分数据库支持更简洁的语法实现需求,比如PostgreSQL可以用DISTINCT ON:
SELECT DISTINCT ON (ID) * FROM t ORDER BY ID, VERSION DESC;
内容的提问来源于stack exchange,提问作者user149691
相关产品推荐
相关产品推荐

