函数应用主要分为如下4类:
1. 统计函数(MAX MIN AVG SUM COUNT等)
2. 排序函数(ROW_NUMBER RANK DENSE_RNAK FIRST FIRST_VALUE LAST LAST_VALUE LAG LEAD 等)
3. 数据分布函数(NTILE CUME_DIST PERCENT_RANK PERCENTILE_CON PERCENTILE_DISC RATIO_TO_REPORT 等)
4. 数学分析函数(CORR COVAR_POP COVAR_SAMP STDDEV STDDEV_SAMP VAR_POP VAR_SAMP VARIANCE 等)
对于大部分人来说,用的最多的是第1和第2类。(第3类中的RATIO_TO_REPORT倒是用的频率还不小)
由于统计函数比较简单,大家都明白具体的用途,也没有什么必要特别再来说明,排序函数在前面一节中已经介绍,因此这里主要说说分析函数。
分析函数计算基于group by的列,分组查询出的行被称为"比照(window)",在根据over()执行过程中,针对每一行都会重新定义比照。比照为"当前行(current row)"确定执行计算的行的范围。这点一定要理解清楚。它是分析函数生成数据的原理。
分析函数与聚合函数有些相似,都有聚合、分组、范围、排序的概念,不过他们之间显而易见的巨大差别就在于:分析函数是每组有多少行就返回多少行(好比多一个伪列)。而聚合函数是每组不管有多少行都被聚合成一行。
测试案例
drop table emp purge;
CREATE TABLE emp
(
emp_id NUMBER(6),
ename VARCHAR2(45),
dept_id NUMBER(4),
hire_date DATE,
sal NUMBER(8,2)
);
创建emp数据
INSERT INTO emp (emp_id, ename, dept_id, hire_date, sal) VALUES (101, 'Tom', 20, TO_DATE('21-09-1989', 'DD-MM-YYYY'), 2000);
INSERT INTO emp (emp_id, ename, dept_id, hire_date, sal) VALUES (102, 'Mike', 20, TO_DATE('13-01-1993', 'DD-MM-YYYY'), 8000);
INSERT INTO emp (emp_id, ename, dept_id, hire_date, sal) VALUES (120, 'John', 50, TO_DATE('18-07-1996', 'DD-MM-YYYY'), 1000);
INSERT INTO emp (emp_id, ename, dept_id, hire_date, sal) VALUES (121, 'Joy', 50, TO_DATE('10-04-1997', 'DD-MM-YYYY'), 4000);
INSERT INTO emp (emp_id, ename, dept_id, hire_date, sal) VALUES (122, 'Rich', 50, TO_DATE('01-05-1995', 'DD-MM-YYYY'), 3000);
INSERT INTO emp (emp_id, ename, dept_id, hire_date, sal) VALUES (123, 'Kate', 50, TO_DATE('10-10-1997', 'DD-MM-YYYY'), 5000);
INSERT INTO emp (emp_id, ename, dept_id, hire_date, sal) VALUES (124, 'Jess', 50, TO_DATE('16-11-1999', 'DD-MM-YYYY'), 6000);
INSERT INTO emp (emp_id, ename, dept_id, hire_date, sal) VALUES (100, 'Stev', 10, TO_DATE('01-01-1990', 'DD-MM-YYYY'), 7000);
COMMIT;
set linesize 1000
set pagesize 1000
col emp_id format 999
col dept_id format 99
col ename format a5
SQL> select * from emp;
SQL> SELECT
emp_id,ename,dept_id,hire_date,sal,
SUM(sal) OVER (PARTITION BY dept_id ORDER BY hire_date) sum_sal,
SUM(sal) OVER (PARTITION BY dept_id ) sum_sal2,
SUM(sal) OVER ( ) sum_sal3
FROM emp;
SQL> SELECT dept_id ,SUM(sal) FROM emp GROUP BY dept_id ORDER BY dept_id;