准备工作:
table:oracle用户scott下的emp表 ;
一. Oracle 从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是
对于每个组返回多行,而聚合函数对于每个组只返回一行。
exp:
这样会报:ORA-00937:非单组分组函数;
结论:聚合函数只能返回1行值。
返回的结果:
结论:这就是每个组返回多行。
二.
over()、over(order by...)与over(partition by...)之间的区别
1.分析函数over()用在聚合函数(max(),sun()....)后面,可返回多行所有结果的聚合值;
exp:如上;
2.over(order by...)用在聚合函数(max(),sun()....)后面,可返回根据排序结果进行统计到当前行的聚合值(即“连续”统计);
exp:
返回的结果:
>
分析:第二行的sum=第一行里的sal+第二行里的sal;
第二行的sum=第一行里的sal+第二行里的sal+第三行里的sal;
.....
结论:返回值是根据排序后的结果,当前所在的行进行统计的。
3.over(partition by...)用在聚合函数(max(),sun()....)后面,可根据pratition by里指定的某一列来统计聚合值。
exp:
返回的结果:
>
分析:每个sum的值都是把deptno相同的sal值进行求和。
结论:根据pratition by里指定的某一列来统计聚合值。
三.一个综合的例子:
exp:
question:
按部门“连续”求总和;
answer:
返回的结果:
>
分析:先根据partition by 进行分组,然后再根据order by 进行排序“连续”统计。
四.一个实际的例子来说明over()分析函数在代码上能简化和提高效率。
question:
查询出管理员工人数最多的人的名字和他管理的人的名字
answer:
1.普通的方法:
2.使用over()分析函数:
输出结果是一样的:
table:oracle用户scott下的emp表 ;
一. Oracle 从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是
对于每个组返回多行,而聚合函数对于每个组只返回一行。
exp:
- select t.empno,t.ename,sum(t.sal) from emp t
结论:聚合函数只能返回1行值。
- select t.empno,t.ename,sum(t.sal)over() sum from emp t
empno | ename | sum |
7369 | SMITH | 142781.99 |
7499 | ALLEN | 142781.99 |
7521 | WARD | 142781.99 |
7566 | JONES | 142781.99 |
7654 | MARTIN | 142781.99 |
7698 | BLAKE | 142781.99 |
7782 | CLARK | 142781.99 |
7788 | SCOTT | 142781.99 |
7839 | KING | 142781.99 |
7844 | TURNER | 142781.99 |
7876 | ADAMS | 142781.99 |
7900 | JAMES | 142781.99 |
7902 | FORD | 142781.99 |
7934 | MILLER | 142781.99 |
结论:这就是每个组返回多行。
二.
over()、over(order by...)与over(partition by...)之间的区别
1.分析函数over()用在聚合函数(max(),sun()....)后面,可返回多行所有结果的聚合值;
exp:如上;
2.over(order by...)用在聚合函数(max(),sun()....)后面,可返回根据排序结果进行统计到当前行的聚合值(即“连续”统计);
exp:
- select t.empno,
- t.deptno,
- t.ename,
- t.sal,
- sum(t.sal) over(order by t.ename) sum
- from emp t
>
empno | deptno | ename | sal | sum |
7876 | 20 | ADAMS | 4646.11 | 4646.11 |
7499 | 30 | ALLEN | 8493.66 | 13139.77 |
7698 | 30 | BLAKE | 15047.69 | 28187.46 |
7782 | 10 | CLARK | 11823.85 | 40011.31 |
7902 | 20 | FORD | 14935.97 | 54947.28 |
7900 | 30 | JAMES | 4935.36 | 59882.64 |
7566 | 20 | JONES | 15086.30 | 74968.94 |
7839 | 10 | KING | 23841.13 | 98810.07 |
7654 | 30 | MARTIN | 6526.80 | 105336.87 |
7934 | 10 | MILLER | 6167.32 | 111504.19 |
7788 | 20 | SCOTT | 12710.16 | 124214.35 |
7369 | 20 | SMITH | 4089.17 | 128303.52 |
7844 | 30 | TURNER | 7843.77 | 136147.29 |
7521 | 30 | WARD | 6634.70 | 142781.99 |
分析:第二行的sum=第一行里的sal+第二行里的sal;
第二行的sum=第一行里的sal+第二行里的sal+第三行里的sal;
.....
结论:返回值是根据排序后的结果,当前所在的行进行统计的。
3.over(partition by...)用在聚合函数(max(),sun()....)后面,可根据pratition by里指定的某一列来统计聚合值。
exp:
- select t.empno,
- t.deptno,
- t.ename,
- t.sal,
- sum(t.sal) over(partition by t.deptno) sum
- from emp t
>
empno | deptno | ename | sal | sum |
7782 | 10 | CLARK | 11823.85 | 41832.3 |
7839 | 10 | KING | 23841.13 | 41832.3 |
7934 | 10 | MILLER | 6167.32 | 41832.3 |
7369 | 20 | SMITH | 4089.17 | 51467.71 |
7876 | 20 | ADAMS | 4646.11 | 51467.71 |
7902 | 20 | FORD | 14935.97 | 51467.71 |
7788 | 20 | SCOTT | 12710.16 | 51467.71 |
7566 | 20 | JONES | 15086.30 | 51467.71 |
7499 | 30 | ALLEN | 8493.66 | 49481.98 |
7698 | 30 | BLAKE | 15047.69 | 49481.98 |
7654 | 30 | MARTIN | 6526.80 | 49481.98 |
7900 | 30 | JAMES | 4935.36 | 49481.98 |
7844 | 30 | TURNER | 7843.77 | 49481.98 |
7521 | 30 | WARD | 6634.70 | 49481.98 |
分析:每个sum的值都是把deptno相同的sal值进行求和。
结论:根据pratition by里指定的某一列来统计聚合值。
三.一个综合的例子:
exp:
question:
按部门“连续”求总和;
answer:
- select t.empno,
- t.deptno,
- t.ename,
- t.sal,
- sum(t.sal) over(partition by t.deptno order by t.ename) sum
- from emp t
>
empno | deptno | ename | sal | sum |
7782 | 10 | CLARK | 11823.85 | 11823.85 |
7839 | 10 | KING | 23841.13 | 35664.98 |
7934 | 10 | MILLER | 6167.32 | 41832.3 |
7876 | 20 | ADAMS | 4646.11 | 4646.11 |
7902 | 20 | FORD | 14935.97 | 19582.08 |
7566 | 20 | JONES | 15086.30 | 34668.38 |
7788 | 20 | SCOTT | 12710.16 | 47378.54 |
7369 | 20 | SMITH | 4089.17 | 51467.71 |
7499 | 30 | ALLEN | 8493.66 | 8493.66 |
7698 | 30 | BLAKE | 15047.69 | 23541.35 |
7900 | 30 | JAMES | 4935.36 | 28476.71 |
7654 | 30 | MARTIN | 6526.80 | 35003.51 |
7844 | 30 | TURNER | 7843.77 | 42847.28 |
7521 | 30 | WARD | 6634.70 | 49481.98 |
分析:先根据partition by 进行分组,然后再根据order by 进行排序“连续”统计。
四.一个实际的例子来说明over()分析函数在代码上能简化和提高效率。
question:
查询出管理员工人数最多的人的名字和他管理的人的名字
answer:
1.普通的方法:
- select d.ename 管理员工人数最多的人的名字, o.ename 他管理的人的名字
- from emp d, emp o
- where o.empno = d.mgr
- and d.empno in
- (select p.empno
- from emp p
- where p.empno in
- (select r.mgr
- from (select e.mgr, count(e.mgr) c from emp e group by e.mgr) r
- where r.c is
- (select max(w.z)
- from (select count(m.mgr) z from emp m group by m.mgr) w)))
- select e.ename 管理员工人数最多的人的名字, j.ename 他管理的人的名字
- from emp e, emp j
- where j.empno = e.mgr
- and e.empno in (select distinct (r.mgr)
- from (select m.mgr,
- count(m.mgr) over(partition by m.mgr order by m.empno) t
- from emp m) r
- where r.t is (select max(y.h)
- from (select count(p.mgr) over(partition by p.mgr order by p.empno) h
- from emp p) y))
管理员工人数最多的人的名字 | 他管理的人的名字 |
BLAKE | KING |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!