组函数:avg sum max min count
group by
having
group by 增强:rollup cube grouping grouping set
一.分组函数
1.常用分组函数
AVG([DISTINCT|ALL]n) -- 求平均值,忽略空值 COUNT({*|[DISTINCT|ALL]expr}) -- 统计个数,其中expr用来判定非空值(使用*计算所有选定行,包括重复行和带有空值的行) MAX([DISTINCT|ALL]expr) -- 求最大值,忽略空值 MIN([DISTINCT|ALL]expr) -- 求最小值,忽略空值 SUM([DISTINCT|ALL]n) -- 求和,忽略空值
注: (1) DISTINCT 使函数只考虑非重复值,ALL则考虑包括重复值在内的所有值。默认为ALL.
(2) 带有expr参数的函数的数据类型可以为CHAR,VARCHAR2,NUMBER,DATE.
(3) 所有分组函数都忽略空值。可以使用NVL,NVL2,或COALESCE函数代替空值
(4) 使用GROUP BY 时,Oralce服务器隐式地按照升序对结果集进行排序。可以使用ORDER BY 更改排序结果。
(5)组函数默认忽略空值。可以使用NVL 函数强制分组函数包含空值,如
select avg(nvl(comm,0)) from emp;
2.语法
SELECT [column,] group_function(column), ... FROM table [WHERE condition] [GROUP BY column] [ORDER BY column];
3.avg() / sum()
只适用于数值型
select avg(salary),sum(salary) from employees where department_id = 80;
4.max() / min()
适用于数值型、字符型、日期型
select max(salary),max(last_name),max(hire_date),min(salary),min(last_name),min(hire_date) from employees;
5.count()
coung(*)包含空值、重复值,count(expr)过滤空值,count(distinct expr)既过滤空值,也过滤重复值
(1) count(1)/count(2)/count(*)表示将表中的每条记录用1/2/*来充当
select count(employee_id),count(1),count(2),count(salary),count(*),count(hire_date),count(commission_pct) from employees;
(2) avg = sum / count
select avg(commission_pct),sum(commission_pct)/count(commission_pct),sum(commission_pct)/107 from employees; --1和2相等
(3) 使用NVL 函数强制分组函数包含空值
select avg(nvl(commission_pct,0)),sum(commission_pct)/107 from employees; --1,2相等
二.group by
使用GROUP BY 子句可以将表中的行分成更小的组,然后使用分组函数返回每一组的汇总信息。
1.语法
SELECT column, group_function(column) FROM table [WHERE condition] [GROUP BY group_by_expression] --即为对哪些列进行分组 [ORDER BY column];
注: (1)SELECT 中出现的列,如果未出现在分组函数中,则GROUP BY子句必须包含这些列
(2)WHERE 子句可以某些行在分组之前排除在外
(3)不能在GROUP BY 中使用列别名
(4) 默认情况下GROUP BY列表中的列按升序排列
(5) GROUP BY 的列可以不出现在分组中
2.示例
按多个字段进行分组
select department_id,job_id,avg(salary),sum(salary) from employees group by department_id , job_id order by department_id;
分组函数的嵌套
select max(avg(sal)) from emp group by deptno;
三.having
(1)若过滤条件中出现了组函数,那么必须使用havin替换where.
(2)若过滤条件中没有组函数,建议使用where,比having 效率高。
select department_id,max(salary) from employees --where max(salary) > 100000 --错误 having max(salary) > 100000 group by department_id;
四.group by 增强
1.Rollup
在Group By 中使用Rollup 产生常规分组汇总行 以及分组小计:
SELECT department_id, job_id, SUM(salary) FROM employees WHERE department_id < 60 GROUP BY ROLLUP(department_id, job_id);
1——常规分组行;
2, 3 ——分层小计行;
Rollup 后面跟了n个字段,就将进行n+1次分组,从右到左每次减少一个字段进行分组;然后进行union
2.Cube
在Group By 中使用Cube 产生Rollup结果集 + 多维度的交叉表数据源:
SELECT department_id, job_id, SUM(salary) FROM employees WHERE department_id < 60 GROUP BY CUBE (department_id, job_id) ;
1——常规分组行;
2, 3 、 4 ——分层小计行;其中3是交叉表数据源需要的 job_id 维度层面的小计。
Cube 后面跟了n个字段,就将进行2的N次方的分组运算,然后进行;
3.Grouping
Grouping函数: Rollup 和 Cube有点抽象,他分别相当于n+1 和 2的n次方常规 Group by 运算;那么在Rollup 和 Cube的结果集中如何很明确的看出哪些行是针对那些列或者列的组合进行分组运算的结果的? 答案是可以使用Grouping 函数; 没有被Grouping到返回1,否则返回0.
SELECT department_id DEPTID, job_id JOB, SUM(salary), GROUPING(department_id) GRP_DEPT, GROUPING(job_id) GRP_JOB FROM employees WHERE department_id < 50 GROUP BY ROLLUP(department_id, job_id);
第1行, department_id 和 job_id都被用到了,所以都返回0; 第2行, job_id 没有被用到,所以返回1; 第3行, department_id 和job_id 都没有被用到,所以都返回1
4.Grouping Set
使用Grouping Set 来代替多次UNION:
SELECT department_id, job_id, manager_id,avg(salary) FROM employees GROUP BY GROUPING SETS ((department_id,job_id), (job_id,manager_id));