Oracle SQL如何仅保留每个ID分组下DAY_ID最大的记录
Oracle分组保留字段最大值对应所有行的SQL实现
需求说明
在Oracle SQL Developer环境下处理包含JOB_ID、DAY_ID两个字段的数据集,需遵循以下处理规则:
- 按
JOB_ID字段对数据分组 - 每组仅保留
DAY_ID为当前分组最大值的行 - 同分组下如果存在多条
DAY_ID等于最大值的记录,需全部保留,不得去重
原始数据集
| JOB_ID | DAY_ID |
|---|---|
| 430 | 120 |
| 430 | 720 |
| 530 | 120 |
| 530 | 620 |
| 630 | 120 |
| 630 | 120 |
| 630 | 620 |
| 630 | 620 |
期望输出结果
| JOB_ID | DAY_ID |
|---|---|
| 430 | 720 |
| 530 | 620 |
| 630 | 620 |
| 630 | 620 |
可用SQL写法
以下两种写法均能完全满足需求,可根据实际场景选择:
窗口函数写法(推荐)
用RANK()窗口函数实现,性能优异,易扩展,适合大数据量场景:SELECT JOB_ID, DAY_ID FROM ( SELECT JOB_ID, DAY_ID, RANK() OVER(PARTITION BY JOB_ID ORDER BY DAY_ID DESC) AS row_rank FROM 替换为你的实际表名 ) WHERE row_rank = 1;注意不要用
ROW_NUMBER(),该函数会给相同值的行打不同排名,会导致同组下重复的最大值记录被错误过滤。关联子查询写法
语法简单无窗口函数依赖,兼容所有Oracle版本:SELECT t1.JOB_ID, t1.DAY_ID FROM 替换为你的实际表名 t1 WHERE t1.DAY_ID = ( SELECT MAX(t2.DAY_ID) FROM 替换为你的实际表名 t2 WHERE t2.JOB_ID = t1.JOB_ID );
两种写法的特点:
- 窗口函数写法只需要全表扫描一次,数据量超过10万条时性能远高于子查询写法
- 子查询写法逻辑直白,不需要掌握窗口函数语法即可快速理解修改
内容的提问来源于stack exchange,提问作者ItzCamm
相关产品推荐
相关产品推荐

