oracle的分析函数over
参考地址:https://www.cnblogs.com/chinas/p/7058771.html?utm_source=itdadao&utm_medium=referral#_lab2_0_0 说明:聚合函数(如sum()、max()等)可以计算基于组的某种聚合值,但是聚合函数对于某个组只能返回一行记录。若想对于某组返回多行记录,则需要使用分析函数。 1、rank()/dense_rank over(partition by ... order by ...)说明:over()在什么条件之上;? partition by 按哪个字段划分组; order by 按哪个字段排序; 注意: (1)使用rank()/dense_rank() 时,必须要带order by否则非法 (2)rank()/dense_rank()分级的区别: rank(): 跳跃排序,如果有两个第一级时,接下来就是第三级。 示例:查询每个部门工资最高的员工信息 方法一: SELECT E.ENAME,E.JOB,E.SAL,E.DEPTNO
FROM (SELECT E.ENAME,E.DEPTNO,RANK() OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL DESC) RANK
FROM SCOTT.EMP E) E
WHERE E.RANK = 1
方法二: SELECT E.ENAME,DENSE_RANK() OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL DESC) RANK
FROM SCOTT.EMP E) E
WHERE E.RANK = 1;
结果: 2、min()/max() over(partition by ...)查询员工信息的同时,查询员工工资与所在部门最低、最高工资的差额 SELECT E.ENAME,MIN(E.SAL) OVER(PARTITION BY E.DEPTNO) MIN_SAL,MAX(E.SAL) OVER(PARTITION BY E.DEPTNO) MAX_SAL,NVL(E.SAL - MIN(E.SAL) OVER(PARTITION BY E.DEPTNO),0) DIFF_MIN_SAL,NVL(MAX(E.SAL) OVER(PARTITION BY E.DEPTNO) - E.SAL,0) DIFF_MAX_SAL FROM SCOTT.EMP E; 结果: 注:这里没有排序条件,若加上order by 排序条件, MAX() OVER(PARTITION BY .. ORDER BY .. DESC) 排序规则只能为desc,否则不起作用,将查询到目前为止排序值最高字段的对应值 3、lead()/lag() over(partition by ... order by ...) 取前面/后面第n行记录说明: lead(列名,n,m): 当前记录后面第n行记录的<列名>的值,没有则默认值为m;如果不带参数n,m,则查找当前记录后面第一行的记录<列名>的值,没有则默认值为null。 ?示例:查询个人工资与比自己高一位、低一位的工资的差额 SELECT E.ENAME,LEAD(E.SAL,1,0) OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL) LEAD_SAL,--记录后面第n行记录 LAG(E.SAL,0) OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL) LAG_SAL,--记录前面第n行记录 NVL(LEAD(E.SAL) OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL) - E.SAL,0) DIFF_LEAD_SAL,NVL(E.SAL - LEAD(E.SAL) OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL),0) DIFF_LAG_SAL FROM SCOTT.EMP E; 结果: ? 4、FIRST_VALUE/LAST_VALUE() OVER(PARTITION BY ...) 取首尾记录SELECT E.EMPNO,E.ENAME,E.MGR,FIRST_VALUE(E.SAL) OVER(PARTITION BY E.DEPTNO) FIRST_SAL,LAST_VALUE(E.SAL) OVER(PARTITION BY E.DEPTNO) LAST_SAL
FROM SCOTT.EMP E;
结果: 5、ROW_NUMBER() OVER(PARTITION BY.. ORDER BY ..) 排序(应用:分页)SELECT E.ENAME,E.ROW_NUM
FROM (SELECT E.ENAME,ROW_NUMBER() OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL) ROW_NUM
FROM SCOTT.EMP E) E
WHERE E.ROW_NUM > 3;
补充: 类似分页的操作还可以用rownum、fetch(Oracle12C后的新特性)实现 结果: ? 6、sum/avg/count() over(partition by ..)SELECT E.ENAME,SUM(E.SAL) OVER(PARTITION BY E.DEPTNO) SUM_SAL,--统计某组中的总计值 AVG(E.SAL) OVER(PARTITION BY E.DEPTNO) AVG_SAL,--统计某组中的平均值 COUNT(E.SAL) OVER(PARTITION BY E.DEPTNO) COUNT_SAL --按某列分组,并统计该组中记录数量 FROM SCOTT.EMP E; 结果: 示例2(全统计):为数据集统计部门销售总和,全公司销售总和,部门销售均值,全公司销售均值 SELECT A.DEPT_ID,A.SALE_DATE,A.GOODS_TYPE,A.SALE_CNT,SUM(A.SALE_CNT) OVER(PARTITION BY A.DEPT_ID) DEPT_TOTAL,--部门销售总和 SUM(A.SALE_CNT) OVER() CMP_TOTAL,--公司销售总额 AVG(A.SALE_CNT) OVER(PARTITION BY A.DEPT_ID) DEPT_AVG,--部门销售均值 AVG(A.SALE_CNT) OVER() CMP_AVG --公司销售均值 FROM LEARN_FUN_KEEP A; 7、?rows/range between … preceding and … following 上下范围内求值说明:unbounded:不受控制的,无限的 rows between … preceding and … following示例1:显示各部门员工的工资,并附带显示该部门的最高工资 SELECT E.DEPTNO,E.EMPNO,LAST_VALUE(E.SAL) OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL ROWS /*LAST_VALUE(E.SAL) OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL ROWS*/ --unbounded preceding and unbouned following针对当前所有记录的前一条、后一条记录,也就是表中的所有记录 --unbounded:不受控制的,无限的 --preceding:在...之前 --following:在...之后 -- ORACLE默认是升序 BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) MAX_SAL FROM SCOTT.EMP E; SELECT E.DEPTNO, 结果: 示例2:对各部门进行分组,并附带显示第一行至当前行的汇总 SELECT E.DEPTNO,--注意ROWS BETWEEN unbounded preceding AND current row 是指第一行至当前行的汇总 SUM(E.SAL) OVER(PARTITION BY E.DEPTNO ORDER BY E.ENAME ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW )MAX_SAL FROM SCOTT.EMP E; 结果: 示例3:当前行至最后一行的汇总 SELECT EMPNO,ENAME,DEPTNO,SAL,--注意ROWS BETWEEN current row AND unbounded following 指当前行到最后一行的汇总 SUM(SAL) OVER(PARTITION BY DEPTNO ORDER BY ENAME ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) MAX_SAL FROM SCOTT.EMP; 结果: 示例4:当前行的上一行(rownum-1)到当前行的汇总 SELECT EMPNO,--注意ROWS BETWEEN 1 preceding AND current row 是指当前行的上一行(rownum-1)到当前行的汇总 SUM(SAL) OVER(PARTITION BY DEPTNO ORDER BY ENAME ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) max_sal FROM SCOTT.EMP; 结果: 示例5:当前行的上一行(rownum-1)到当前行的下两行(rownum+2)的汇总? SELECT EMPNO,--注意ROWS BETWEEN 1 preceding AND 1 following 是指当前行的上一行(rownum-1)到当前行的下辆行(rownum+2)的汇总 SUM(SAL) OVER(PARTITION BY DEPTNO ORDER BY ENAME ROWS BETWEEN 1 PRECEDING AND 2 FOLLOWING) max_sal FROM SCOTT.EMP; 结果: 8、NULLS FIRST/LAST?将空值字段记录放到最前或最后显示说明: 通过RANK()、DENSE_RANK()、ROW_NUMBER()对记录进行全排列、分组排列取值,但有时候,会遇到空值的情况,空值会影响得到的结果的正确性 SELECT E.ENAME,RANK() OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL NULLS LAST)
FROM SCOTT.EMP E;
结果: 2、NTILE(n)说明:NTILE函数对一个数据分区中的有序结果集进行划分,将其分组为各个桶,并为每个小组分配一个唯一的组编号。这个函数在统计分析中是很有用的。例如,如果想移除异常值,你可以将它们分组到顶部或底部的桶中,然后在统计分析的时候将这些值排除。ORACLE数据库统计信息收集也使用NTILE函数来计算直方图信息边界。在统计学术语中,NTILE函数创建等宽直方图信息。 SELECT E.ENAME,NTILE(3) OVER(ORDER BY E.SAL DESC NULLS LAST) ALL_CMP,--若只取前三分之一,ALL_CMP=1即可,若只取中间三分之一,ALL_CMP=2即可 NTILE(3) OVER(PARTITION BY E.DEPTNO ORDER BY E.SAL DESC NULLS LAST) ALL_DEPT --每个部门的分成三部分 FROM SCOTT.EMP E 结果: 3、keep(dense_rank first/last)说明: 1.keep(dense_rank first/last) 这句话的含义是什么? 示例:查看部门 D02 内,销售记录时间最早,销售量最小的记录。 SELECT A.DEPT_ID,MIN(A.SALE_CNT) KEEP(DENSE_RANK FIRST ORDER BY A.SALE_DATE) MIN_EARLY_DATE FROM LEARN_FUN_KEEP A WHERE A.DEPT_ID = ‘D02‘ GROUP BY A.DEPT_ID; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |