下面以scott用户为例:
SQL> select * from emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980-12-17 800.00 20
7499 ALLEN SALESMAN 7698 1981-2-20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981-2-22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981-4-2 2975.00 20
7654 MARTIN SALESMAN 7698 1981-9-28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981-5-1 2850.00 30
7782 CLARK MANAGER 7839 1981-6-9 2450.00 10
7788 SCOTT ANALYST 7566 1987-4-19 3000.00 20
7839 KING PRESIDENT 1981-11-17 5000.00 10
7844 TURNER SALESMAN 7698 1981-9-8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987-5-23 1100.00 20
7900 JAMES CLERK 7698 1981-12-3 950.00 30
7902 FORD ANALYST 7566 1981-12-3 3000.00 20
7934 MILLER CLERK 7782 1982-1-23 1300.00 10
注意over()条件的不同,使用sum(sal) over(order by ename) 查询员工的sal“连续”求和
SQL> select deptno,ename,sal,sum(sal) over(order by ename) from emp;
DEPTNO ENAME SAL SUM(SAL)OVER(ORDERBYENAME)
------ ---------- --------- --------------------------
20 ADAMS 1100.00 1100
30 ALLEN 1600.00 2700
30 BLAKE 2850.00 5550
10 CLARK 2450.00 8000
20 FORD 3000.00 11000
30 JAMES 950.00 11950
20 JONES 2975.00 14925
10 KING 5000.00 19925
30 MARTIN 1250.00 21175
10 MILLER 1300.00 22475
20 SCOTT 3000.00 25475
20 SMITH 800.00 26275
30 TURNER 1500.00 27775
30 WARD 1250.00 29025
先按照ename排序,然后连续求和。
如果over()里面的内容是空的等同于sum(sal) :
SQL> select deptno,ename,sal,sum(sal) over(), sum(sal) over(order by ename) from emp;
DEPTNO ENAME SAL SUM(SAL)OVER() SUM(SAL)OVER(ORDERBYENAME)
------ ---------- --------- -------------- --------------------------
20 ADAMS 1100.00 29025 1100
30 ALLEN 1600.00 29025 2700
30 BLAKE 2850.00 29025 5550
10 CLARK 2450.00 29025 8000
20 FORD 3000.00 29025 11000
30 JAMES 950.00 29025 11950
20 JONES 2975.00 29025 14925
10 KING 5000.00 29025 19925
30 MARTIN 1250.00 29025 21175
10 MILLER 1300.00 29025 22475
20 SCOTT 3000.00 29025 25475
20 SMITH 800.00 29025 26275
30 TURNER 1500.00 29025 27775
30 WARD 1250.00 29025 29025
sum(sal) over(partition by deptno)按照部门编号进行查询:
SQL> select deptno,ename,sal,sum(sal) over(partition by deptno) from emp;
DEPTNO ENAME SAL SUM(SAL)OVER(PARTITIONBYDEPTNO
------ ---------- --------- ------------------------------
10 CLARK 2450.00 8750
10 KING 5000.00 8750
10 MILLER 1300.00 8750
20 JONES 2975.00 10875
20 FORD 3000.00 10875
20 ADAMS 1100.00 10875
20 SMITH 800.00 10875
20 SCOTT 3000.00 10875
30 WARD 1250.00 9400
30 TURNER 1500.00 9400
30 ALLEN 1600.00 9400
30 JAMES 950.00 9400
30 BLAKE 2850.00 9400
30 MARTIN 1250.00 9400
sum(sal) over(order by deptno,ename)不按部门“连续”求总和:
SQL> select deptno,ename,sal,sum(sal) over(partition by deptno,ename) from emp;
DEPTNO ENAME SAL SUM(SAL)OVER(PARTITIONBYDEPTNO
------ ---------- --------- ------------------------------
10 CLARK 2450.00 2450
10 KING 5000.00 5000
10 MILLER 1300.00 1300
20 ADAMS 1100.00 1100
20 FORD 3000.00 3000
20 JONES 2975.00 2975
20 SCOTT 3000.00 3000
20 SMITH 800.00 800
30 ALLEN 1600.00 1600
30 BLAKE 2850.00 2850
30 JAMES 950.00 950
30 MARTIN 1250.00 1250
30 TURNER 1500.00 1500
30 WARD 1250.00 1250
sum(sal) over(partition by deptno order by ename) 按部门连续求和:
SQL> select deptno,ename,sal,sum(sal) over(partition by deptno order by ename) from emp;
DEPTNO ENAME SAL SUM(SAL)OVER(PARTITIONBYDEPTNO
------ ---------- --------- ------------------------------
10 CLARK 2450.00 2450
10 KING 5000.00 7450
10 MILLER 1300.00 8750
20 ADAMS 1100.00 1100
20 FORD 3000.00 4100
20 JONES 2975.00 7075
20 SCOTT 3000.00 10075
20 SMITH 800.00 10875
30 ALLEN 1600.00 1600
30 BLAKE 2850.00 4450
30 JAMES 950.00 5400
30 MARTIN 1250.00 6650
30 TURNER 1500.00 8150
30 WARD 1250.00 9400
总的效果:
SQL> select deptno,ename,sal,
2 sum(sal) over (partition by deptno order by ename) "部门连续求和",
3 sum(sal) over (partition by deptno) "部门总和",
4 100*round(sal/sum(sal) over (partition by deptno),4) "部门份额",
5 sum(sal) over (order by deptno,ename) "连续求和",
6 sum(sal) over () "总和",
7 100*round(sal/sum(sal) over (),4) "总份额(%)" from emp;
DEPTNO ENAME SAL 部门连续求和 部门总和 部门份额 连续求和 总和 总份额(%)
------ ---------- --------- ------------ ---------- ---------- ---------- ---------- ----------
10 CLARK 2450.00 2450 8750 28 2450 29025 8.44
10 KING 5000.00 7450 8750 57.14 7450 29025 17.23
10 MILLER 1300.00 8750 8750 14.86 8750 29025 4.48
20 ADAMS 1100.00 1100 10875 10.11 9850 29025 3.79
20 FORD 3000.00 4100 10875 27.59 12850 29025 10.34
20 JONES 2975.00 7075 10875 27.36 15825 29025 10.25
20 SCOTT 3000.00 10075 10875 27.59 18825 29025 10.34
20 SMITH 800.00 10875 10875 7.36 19625 29025 2.76
30 ALLEN 1600.00 1600 9400 17.02 21225 29025 5.51
30 BLAKE 2850.00 4450 9400 30.32 24075 29025 9.82
30 JAMES 950.00 5400 9400 10.11 25025 29025 3.27
30 MARTIN 1250.00 6650 9400 13.3 26275 29025 4.31
30 TURNER 1500.00 8150 9400 15.96 27775 29025 5.17
30 WARD 1250.00 9400 9400 13.3 29025 29025 4.31
- oracle over()函数,从oracle 8i开始支持,后面的版本支持的比较好.
- 通常在做统计分析时我们都想尽可能多滴选择出原始列和统计值列,但是这样group by后面就必须跟随更多的列,使用分析函数可以避免使用group by时选择出来的列名必须出现在group by列表中的痛苦.
- --1、over() 注(9i下over括号内必须有内容,不允许为空,本文所有示例均在10g下运行的)
- --所有人的总工资
- select a.empno, a.ename, sum(a.sal) over() total from emp a;
- EMPNO ENAME TOTAL
- 7369 SMITH 29025
- 7499 ALLEN 29025
- 7521 WARD 29025
- 7566 JONES 29025
- 7654 MARTIN 29025
- 7698 BLAKE 29025
- 7782 CLARK 29025
- 7788 SCOTT 29025
- 7839 KING 29025
- 7844 TURNER 29025
- 7876 ADAMS 29025
- 7900 JAMES 29025
- 7902 FORD 29025
- 7934 MILLER 29025
- --2、over(partition by ...) 分组统计
- --统计部门的平均工资
- select a.empno,
- a.ename,
- b.dname,
- to_char(round(avg(a.sal) over(partition by b.dname), 2),'$999,999,999.99') dept_avg
- from emp a, dept b
- where a.deptno = b.deptno;
- EMPNO ENAME DNAME DEPT_AVG
- 7934 MILLER ACCOUNTING $2,916.67
- 7839 KING ACCOUNTING $2,916.67
- 7782 CLARK ACCOUNTING $2,916.67
- 7876 ADAMS RESEARCH $2,175.00
- 7902 FORD RESEARCH $2,175.00
- 7566 JONES RESEARCH $2,175.00
- 7369 SMITH RESEARCH $2,175.00
- 7788 SCOTT RESEARCH $2,175.00
- 7521 WARD SALES $1,566.67
- 7844 TURNER SALES $1,566.67
- 7499 ALLEN SALES $1,566.67
- 7900 JAMES SALES $1,566.67
- 7698 BLAKE SALES $1,566.67
- 7654 MARTIN SALES $1,566.67
- --查询出管理员工人数最多的人的名字和他管理的人的名字
- select b.ename, t.ename, t.mgr, t.cnt
- from (select a.empno,
- a.ename,
- a.mgr,
- count(1) over(partition by a.mgr) cnt
- from emp a) t,
- emp b
- where t.mgr = b.empno;
- ENAME ENAME MGR CNT
- JONES SCOTT 7566 2
- JONES FORD 7566 2
- BLAKE WARD 7698 5
- BLAKE TURNER 7698 5
- BLAKE ALLEN 7698 5
- BLAKE JAMES 7698 5
- BLAKE MARTIN 7698 5
- CLARK MILLER 7782 1
- SCOTT ADAMS 7788 1
- KING BLAKE 7839 3
- KING JONES 7839 3
- KING CLARK 7839 3
- FORD SMITH 7902 1
- --3、over(order by ...) 排序统计
- select a.empno,
- a.deptno,
- a.ename,
- a.sal,
- sum(a.sal) over(order by a.ename) sum
- from emp a;
- EMPNO DEPTNO ENAME SAL SUM
- 7876 20 ADAMS 1100.00 1100
- 7499 30 ALLEN 1600.00 2700
- 7698 30 BLAKE 2850.00 5550
- 7782 10 CLARK 2450.00 8000
- 7902 20 FORD 3000.00 11000
- 7900 30 JAMES 950.00 11950
- 7566 20 JONES 2975.00 14925
- 7839 10 KING 5000.00 19925
- 7654 30 MARTIN 1250.00 21175
- 7934 10 MILLER 1300.00 22475
- 7788 20 SCOTT 3000.00 25475
- 7369 20 SMITH 800.00 26275
- 7844 30 TURNER 1500.00 27775
- 7521 30 WARD 1250.00 29025
- --4、over(partition by ... order by ...) 分组排序统计
- --统计各部门薪水前三名的人员
- select t.*
- from (select rank() over(partition by b.dname order by a.sal desc) rk,
- a.empno,
- a.ename,
- b.dname,
- a.sal
- from emp a, dept b
- where a.deptno = b.deptno) t
- where t.rk <= 3;
- RK EMPNO ENAME DNAME SAL
- 1 7839 KING ACCOUNTING 5000.00
- 2 7782 CLARK ACCOUNTING 2450.00
- 3 7934 MILLER ACCOUNTING 1300.00
- 1 7902 FORD RESEARCH 3000.00
- 1 7788 SCOTT RESEARCH 3000.00
- 3 7566 JONES RESEARCH 2975.00
- 1 7698 BLAKE SALES 2850.00
- 2 7499 ALLEN SALES 1600.00
- 3 7844 TURNER SALES 1500.00