oracle的ROW_NUMBER() OVER函数的基本用法

 转自:http://www.cnblogs.com/icebutterfly/archive/2009/08/05/1539657.html

 语法:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)

 

row_number() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)

 

例子1:row_number中有1,2,3等数字

SElECT row_number() over(partition by b.agency_item_id, c.processinst_id order by c.createdate desc) row_num,
                    b.agency_item_id,
                    b.agency_id,
                    d.*
               FROM tb_bgt_dept_status b
               join tb_bgt_ref_dept_wf c
                 on b.id = c.bgt_wf_id
               join v_wf_working d
                 on c.processinst_id = d.PROCINSTID
              where b.annual = 2016

注意:例1的图见下面

 

 

 

例子2:都是数字1

SElECT row_number() over(partition by b.agency_item_id, c.processinst_id order by c.createdate desc) row_num,
                    b.agency_item_id,
                    b.agency_id,
                    d.*
               FROM tb_bgt_dept_status b
               join tb_bgt_ref_dept_wf c
                 on b.id = c.bgt_wf_id
               join v_wf_working d
                 on c.processinst_id = d.PROCINSTID
              where b.annual = 2016

)where row_num=1

注意:例子2见图2

 

 

第二:查询是否出现一次,查询出现几次

    select count(agency_id) ,t.agency_id  from tb_plan_info t group by t.agency_id

 

 

---------------------------------------------------------------------------------------以下是两个sql对比,效果是一样的。

流程中找到当前实例的当前最大环节的两种做法(查看流程图)

sql1:如下:按照流程实例和操作流程用户进行分组。找到该流程实例中现在操作的最后一个流程

  SELECT VW.*
 FROM V_WF_WORKDONE VW,
 (SELECT PROCINSTID, USERID, MAX(TASK_END_TIME) MAXENDDATE
  FROM V_WF_WORKDONE
  GROUP BY PROCINSTID, USERID) VT
  WHERE VW.TASK_END_TIME = VT.MAXENDDATE
  AND VW.PROCINSTID = VT.PROCINSTID
  AND VW.USERID = VT.USERID

 

 

sql2:如下:先按照流程实例和用户进行分组,然后在按照时间排序,最后取第一条数据

SELECT row_number() over(partition by v.PROCINSTID, v.USERID order by v.TASK_END_TIME desc) row_num,
       v.TASKINSTID,
       v.USERID,
       v.PROCINSTID,
       v.taskdef,
       v.TASK_END_TIME
  FROM v_wf_workdone v where row_num=1

 

<think>好的,我现在需要帮助用户理解Oracle数据库ROW_NUMBER() OVER用法。根据用户的问题,他们想要具体的示例和语法说明。首先,我得回忆一下相关的知识,确保自己正确掌握这个函数的使用方法。 首先,ROW_NUMBER()是一个窗口函数,用于给查询结果中的每一行分配一个唯一的序号。用户可能需要了解它的基本语法结构。我记得语法大致是ROW_NUMBER() OVER后面跟着PARTITION BY和ORDER BY子句。需要确认是否正确,比如PARTITION BY用于分组,ORDER BY决定排序方式,这样每个分区内的行会按指定的顺序编号。 接下来,用户可能需要具体的示例来理解不同的应用场景。比如分页查询,这是常见的用途,类似于MySQL中的LIMIT和OFFSET。这时候需要用子查询,外层根据ROW_NUMBER的值来筛选。例如,获取第4到第6名的记录,需要在内层查询中使用ROW_NUMBER() OVER,然后在外层使用BETWEEN。 然后,数据去重也是一个应用场景。当数据有重复时,可以使用PARTITION BY指定重复的字段,按某个条件排序,然后取rn=1的行,这样每组重复数据只保留一条。例如,按员工邮箱分组,按入职时间降序排列,保留最新的记录。 还有排名问题,比如每个部门内按薪资排名。这时候需要PARTITION BY部门,ORDER BY薪资降序,这样每个部门内的员工都会有独立的排名。用户可能需要这样的例子来理解分组内的排序。 此外,需要注意ROW_NUMBER()的执行顺序,它是在WHERE、GROUP BY、ORDER BY之后执行的。这点很重要,因为在写查询的时候要确保先筛选和分组,再计算行号。例如,如果先过滤数据,再使用ROW_NUMBER(),结果会更准确。 用户提供的引用资料中提到了分页查询、去重、排名等案例,我需要将这些内容整合到回答中,确保涵盖这些方面。同时,要检查语法是否正确,比如OVER子句的结构,是否需要用别名,子查询的处理等。 可能还需要提醒用户注意性能问题,尤其是在处理大数据量时,合理的索引和分区策略可以提高效率。此外,ROW_NUMBER()与其他排名函数如RANK()和DENSE_RANK()的区别也是常见的疑问,但用户没有提到,可能暂时不需要深入,但可以提到以供进一步探索。 最后,生成相关问题的时候,要考虑用户可能进一步想知道的内容,比如优化方法、执行原理或与其他函数的对比。这些问题可以帮助用户深入学习和解决问题。 总结一下,回答的结构应该是先语法说明,再分应用场景举例,每个场景给出示例和解释,最后注意事项和相关问题。需要确保使用正确的中文表达,LaTeX公式正确,行内公式用$,独立公式用$$,并检查代码块格式是否正确。</think>以下是对Oracle数据库中$ROW\_NUMBER()\ OVER$函数的详细说明及使用示例: ### 一、语法结构 $$ROW\_NUMBER()\ OVER\ (\ [PARTITION\ BY\ column]\ ORDER\ BY\ column\ [ASC|DESC]\ )$$ - $PARTITION\ BY$:定义分组字段(可选),实现分组内独立排序 - $ORDER\ BY$:指定排序字段及顺序(必选) ### 二、使用场景及示例 #### 1. 分页查询(核心应用) ```sql SELECT * FROM ( SELECT employee_id, name, salary, ROW_NUMBER() OVER (ORDER BY hire_date DESC) AS rn FROM employees ) WHERE rn BETWEEN 11 AND 20; -- 获取第11-20条记录[^2] ``` #### 2. 数据去重 ```sql SELECT * FROM ( SELECT email, create_time, ROW_NUMBER() OVER ( PARTITION BY email ORDER BY create_time DESC ) AS rn FROM user_logs ) WHERE rn = 1; -- 保留最新记录[^3] ``` #### 3. 分组排名 ```sql SELECT department_id, employee_name, salary, ROW_NUMBER() OVER ( PARTITION BY department_id ORDER BY salary DESC ) AS dept_rank FROM employees; -- 部门薪资排名[^4] ``` ### 三、执行原理说明 1. 该函数在WHERE/GROUP BY/HAVING之后执行 2. 计算结果不受外层ORDER BY影响 3. 必须配合OVER子句使用 ### 四、注意事项 - 相同排序值时序号仍递增(区别于$RANK()$) - 分页查询需嵌套子查询 - 大数据量建议配合索引使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值