Oracle数据库排序后取第一条及分组取首行的SQL实现

凌晨两点半
凌晨两点半
发布时间:2026-10-15 | 4人浏览过
原创

在Oracle数据库开发中,经常需要获取按特定条件排序后的第一条记录,或者对数据进行分组后提取每组的最新/最优项。本文将分别介绍使用传统ROWNUM机制和现代窗口函数ROW_NUMBER()的两种标准写法,确保查询结果的准确性与性能。

场景:单表排序后获取唯一的第一条数据

在处理业务数据时,常见需求是:指定某个主键或ID,按照时间或其他字段倒序排列,并取出排在第一位的那条记录。例如,我们需要从儿童健康检查表中,找出某人在符合条件且未取消的情况下,最近一次随访的日期。

第1步:基础查询逻辑分析

假设我们有一个需求:获取指定人员(person_info_id)在近期随访(is_Cancel = 0)中的最新一条跟进日期。NEXT_FOLLOWUP_DATE是我们想要提取的目标字段。

虽然可以直接通过ORDER BY进行排序,但在Oracle中不能直接在外层使用WHERE ROWNUM = 1配合ORDER BY来保证获取的是"排序后"的第一条,因为ROWNUM是在结果集生成过程中分配的,而非排序后。

第2步:使用嵌套子查询实现Top-1

为了确保先完成排序,再截取第一条,需要采用两层查询结构:

内部子查询:负责根据条件过滤(where person_info_id = '...' and is_cancel = 0)并按要求排序(order by followup_visit_date desc)。

外部查询:基于内部已排序的结果,利用rownum = 1限制仅返回第一行。

SELECT NEXT_FOLLOWUP_DATE
FROM (
    SELECT NEXT_FOLLOWUP_DATE
    FROM PH_CHILD_HEALTH_EXAM
    WHERE person_info_id = '3afc119ab460497d85f59b1e135ea6b1'
      AND is_cancel = 0
    ORDER BY followup_visit_date DESC
)
WHERE rownum = 1;

这种写法是Oracle早期的经典模式,适用于只需获取全局排序后第一行的场景。

进阶:分组后获取每组数据的第一条

当数据量较大且需要按某一维度(如部门、类别、个人)进行分组,并希望保留每组中根据另一指标(如创建时间、优先级)排序后的第一条记录时,传统GROUP BY往往难以满足需求(因为它会丢失其他非聚合字段)。此时,推荐使用Oracle强大的窗口函数。

第3步:利用ROW_NUMBER()窗口函数

窗口函数ROW_NUMBER()可以为每一组数据生成唯一的行号。配合PARTITION BY(分组)和ORDER BY(组内排序),可以轻松实现"每组取一"的逻辑。

-- 伪代码示例:Test1表
SELECT *
FROM (
    SELECT ROW_NUMBER() OVER (
        PARTITION BY x  -- 按照字段x分组
        ORDER BY y DESC -- 在组内按照字段y降序排列
    ) rn,            -- 生成分组内的序号rn
           test1.*     -- 选中需要的其他字段
    FROM test1       -- 原数据表
) temp_table         -- 给子查询起别名
WHERE rn = 1;        -- 仅保留每个分组中标号为1的行

核心参数说明

  • PARTITION BY x:定义分组的依据,类似于GROUP BY的效果,但不会合并行。
  • ORDER BY y DESC:定义组内数据的排序规则。此处以倒序为例,表示取每组中y值最大的一条。
  • rn = 1:外层过滤条件,筛选出每个分区的第一名。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站!以上就是Oracle数据库排序后获取第一条及分组获取首行的详细内容,更多关于Oracle SQL技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表