oracle中over() 函数用法

本文深入探讨了Oracle数据库中分析函数的使用方法,特别是over()函数的功能及其与sum()和rank()函数的组合应用。通过实际案例,展示了如何根据不同条件进行薪酬总额计算及职位薪资排名。

 

Oracle分析函数是如此的强大,其中over() 函数的用法又尤为的特别,所以将自己的研究结果记录一下。

  个人理解:over() 函数 是对 分析函数的一种条件解释,直接点就是 给分析函数加条件吧。

  在网上看见比较常用的就是 与 sum()、rank() 函数使用。接下来就用分析下两种函数结合over的用法。

  以下测试使用的orace默认的 scott用户下的emp表数据。

  1.sum()结合over()

  Sql代码

  select a.empno as 员工编号

  ,a.ename as 员工姓名

  ,a.deptno as 部门编号

  ,a.sal as 薪酬

  ,sum(sal) over (partition by deptno) 按部门求薪酬总和

  from scott.emp a;

  此段sql 执行的结果为:

  部门编号 员工姓名 员工编码 薪酬 按部门求薪酬总和

  7934 MILLER 10 1300 8750

  7782 CLARK 10 2450 8750

  7839 KING 10 5000 8750

  7369 SMITH 20 800 10875

  7876 ADAMS 20 1100 10875

  7566 JONES 20 2975 10875

  7788 SCOTT 20 3000 10875

  7902 FORD 20 3000 10875

  7900 JAMES 30 950 9400

  7654 MARTIN 30 1250 9400

  7521 WARD 30 1250 9400

  7844 TURNER 30 1500 9400

  7499 ALLEN 30 1600 9400

  7698 BLAKE 30 2850 9400

  可以从结果上看到sum()函数对部门区分进行了求和统计。其中“partition by”官方点的说法叫做"分区",其实就是统计的范围条件。

  下面在给把上面的sql语句改造下 给 over() 函数加上 “order by sal” 会看到一个更过瘾的效果:

  Sql代码

  select a.empno as 员工编号

  ,a.ename as 员工姓名

  ,a.deptno as 部门编号

  ,a.sal as 薪酬

  ,sum(sal) over (partition by deptno) 按部门求薪酬总和

  ,sum(sal) over (partition by deptno order by sal) 按部门累计薪酬

  from scott.emp a;

  结果为:

  部门编号 员工姓名 员工编码 薪酬 按部门求薪酬总和 按部门累计薪酬

  7934 MILLER 10 1300 8750 1300

  7782 CLARK 10 2450 8750 3750

  7839 KING 10 5000 8750 8750

  7369 SMITH 20 800 10875 800

  7876 ADAMS 20 1100 10875 1900

  7566 JONES 20 2975 10875 4875

  7788 SCOTT 20 3000 10875 10875

  7902 FORD 20 3000 10875 10875

  7900 JAMES 30 950 9400 950

  7654 MARTIN 30 1250 9400 3450

  7521 WARD 30 1250 9400 3450

  7844 TURNER 30 1500 9400 4950

  7499 ALLEN 30 1600 9400 6550

  7698 BLAKE 30 2850 9400 9400

  从结果中可以看的 加了 “order by”后对 统计进行一个累加,这里个人理解为对统计范围规定了个统计顺利,一步一步的统计。

  注:此sql语句结尾处不要加“order by”,应为使用的分析函数的(partition by deptno order by sal)

  里已经有排序的语句了,如果再在句尾添加排序子句,一致倒罢了,不一致,结果就令人费解了。

  2.rank()结合over()

  rank函数是分级函数,这个函数必须与 over 函数使用,否则会报一个"缺少窗口函数的错"。我测试sql如下:

  Sql代码

  select a.empno as 员工编号,

  a.sal as 薪资,

  a.job as 岗位,

  rank() OVER(partition by a.job ORDER BY a.sal desc) as 岗位薪资等级

  from scott.emp a;

  查询结果为:

  员工编号 薪资 岗位 等级

  7902 3000 ANALYST 1

  7788 3000 ANALYST 1

  7934 1300 CLERK 1

  7876 1100 CLERK 2

  7900 950 CLERK 3

  7369 800 CLERK 4

  7566 2975 MANAGER 1

  7698 2850 MANAGER 2

  7782 2450 MANAGER 3

  7839 5000 PRESIDENT 1

  7499 1600 SALESMAN 1

  7844 1500 SALESMAN 2

  7654 1250 SALESMAN 3

  7521 1250 SALESMAN 3

 

 

说明:阅读代码时看到:SELECT ROWID, ROW_NUMBER() OVER (ORDER BY DB_BKUP ASC, TIME DESC) TEMP FROM t_pm_history WHERE DB_BKUP < 2 ORDER BY DB_BKUP ASC, TIME DESC,由此查到此文

### Oracle 数据库中 OVER 函数的详细用法和示例 在 Oracle 数据库中,`OVER()` 子句通常与分析函数(Analytic Functions)结合使用,用于执行复杂的计算,而无需对数据进行分组或聚合。通过 `OVER()` 子句,可以在单次扫描数据的过程中完成复杂计算,从而可能改善查询性能[^4]。 #### 1. 基本语法 以下是 `OVER()` 子句的基本语法: ```sql ANALYTIC_FUNCTION() OVER ( [PARTITION BY column_list] [ORDER BY column_list] [window_frame_clause] ) ``` - **`PARTITION BY`**:将数据划分为多个分区,类似于 `GROUP BY`,但不会减少结果集的行数。 - **`ORDER BY`**:定义每个分区内的排序规则。 - **`window_frame_clause`**:指定窗口框架,用于限制分析函数作用的行范围。 #### 2. 示例:LEAD 和 LAG 函数 `LEAD` 和 `LAG` 是常见的分析函数,用于访问同一结果集中前一行或后一行的数据。 以下示例展示了如何使用 `LEAD` 和 `LAG` 函数: ```sql SELECT employee_id, department_id, salary, LEAD(salary) OVER (PARTITION BY department_id ORDER BY salary) AS next_salary, LAG(salary) OVER (PARTITION BY department_id ORDER BY salary) AS prev_salary FROM employees; ``` 此查询为每个部门中的员工按薪资排序,并显示当前行的下一行薪资(`next_salary`)和上一行薪资(`prev_salary`)[^4]。 #### 3. 示例:RATIO_TO_REPORT 函数 `RATIO_TO_REPORT` 函数用于计算某列值占其所在分区内总和的比例。 以下示例展示了如何使用 `RATIO_TO_REPORT` 函数: ```sql SELECT department_id, employee_id, salary, RATIO_TO_REPORT(salary) OVER (PARTITION BY department_id) AS salary_ratio FROM employees; ``` 此查询计算每个员工薪资在其所属部门总薪资中的比例[^4]。 #### 4. 示例:ROW_NUMBER 函数 `ROW_NUMBER` 函数为每一行分配一个唯一的序号,基于 `PARTITION BY` 和 `ORDER BY` 的规则。 以下示例展示了如何使用 `ROW_NUMBER` 函数: ```sql SELECT department_id, employee_id, salary, ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rank FROM employees; ``` 此查询为每个部门中的员工按薪资从高到低排序,并分配排名[^4]。 #### 5. 窗口框架子句 窗口框架子句允许进一步控制分析函数作用的行范围。例如,可以指定仅考虑当前行之前的若干行或之后的若干行。 以下示例展示了如何使用窗口框架子句: ```sql SELECT employee_id, department_id, salary, SUM(salary) OVER ( PARTITION BY department_id ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_sum FROM employees; ``` 此查询为每个部门中的员工按薪资排序,并计算截至当前行的累积薪资总和。 --- ### 注意事项 虽然分析函数减少了数据处理的层次和重复计算,但在处理大数据量和高度复杂查询时,合理的索引设置和其他查询优化策略仍然是提高 SQL 执行效率的关键。建议使用 `EXPLAIN PLAN` 等工具分析 SQL 执行路径,并根据实际情况决定是否以及如何利用分析函数进行优化[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值