select * from emp;

开始之前需要导入一些表,下载地址:https://yuyunyaohui.lanzous.com/ivPKcdnlecd 导入方法:

示例数据:员工表emp、部门表dept、工资级别表salgrade

select count 不使用索引 select 不包含_oracle

一、分组函数的概念

什么是分组函数?

分组函数作用于一组数据,并对一组数据返回一个值。

select count 不使用索引 select 不包含_oracle_02

二、分组函数的使用

SELECT     [column,] group function(column),…
FROM 	    table
[WHERE   condition]
[GROUP BY   column]
[ORDER BY   column]

三、常用的分组函数

1、AVG(平均值)和SUM(合计)函数

求出员工的平均工资和工资的总额

select avg(sal),sum(sal) from emp;

select count 不使用索引 select 不包含_数据库_03

2、MIN(最小值)和MAX(最大值)函数

求出员工工资的最大值和最小值

select min(sal),max(sal) from emp;

select count 不使用索引 select 不包含_oracle_04

3、COUNT(计数)函数

求出员工的总人数

select count(*) from emp;
select count(empno) from emp;

select count 不使用索引 select 不包含_select count 不使用索引_05

4、DISTINCT(distinct)关键字

求出部门数

select count(distinct deptno) from emp;

select count 不使用索引 select 不包含_sql_06

5、LISTAGG:行转列

set linesize 200;
col 部门中员工的姓名 for a60;
select deptno 部门号,listagg(ename,',') within group (order by ename) 部门中员工的姓名
from emp group by deptno;

select count 不使用索引 select 不包含_数据库_07

6、分组函数与空值

分组函数会自动忽略空值

例1:统计员工的平均工资

select sum(sal)/count(*) 一,sum(sal)/count(sal) 二,avg(sal) 三 from emp;

select count 不使用索引 select 不包含_数据库_08


例2:统计员工的平均奖金

select sum(comm)/count(*) 一, sum(comm)/count(comm) 二, avg(comm) 三 from emp;

select count 不使用索引 select 不包含_数据库_09

7、在分组函数中使用NVL函数

注意:NVL函数使分组函数无法忽略空值

select count(*),count(comm) from emp;
select count(*),count(nvl(comm,0)) from emp;

select count 不使用索引 select 不包含_sql_10


使用GROUP BY 子句数据分组

select count 不使用索引 select 不包含_oracle_11


三、分组数据

GROUP BY 子句语法

SELECT     column, group function(column),…
FROM 	    table
[WHERE   condition]
[GROUP BY   group _by_expression]
[ORDER BY   column];

1、可以使用GROUP BY子句将表中的数据分成若干组

(1)在select列表中所有未包含在组函数中的列都应该包含在GROUP BY子句中

例:求每个部门的平均工资,要求显示:部门号,部门平均工资

select deptno,avg(sal)
from emp
group by deptno;

select count 不使用索引 select 不包含_sql_12

SELECT     a,b,c,组函数(x)
FROM 	 table 
GROUP BY   a,b,c;

(2)包含在GROUP BY子句中的列不必包含在select列表中

例:求每个部门的平均工资,要求显示:部门平均工资

select avg(sal)
from emp
group by deptno;

select count 不使用索引 select 不包含_oracle_13

SELECT    组函数(x)
FROM 	 table 
GROUP BY   a,b,c;

2、使用多个列分组

select count 不使用索引 select 不包含_sql_14

例:按部门、不同的职位,统计员工的工资总额

select deptno,empjob,sum(sal)
from emp
group by deptno,empjob
order by deptno;

select count 不使用索引 select 不包含_oracle_15

3、过滤分组

having子句的使用

select count 不使用索引 select 不包含_分组函数_16

having子句的语法

SELECT         column, group_function(column),…
FROM 	        table
[WHERE        condition]
[GROUP BY   group_by_expression]
[HAVING  	  group_condition]
[ORDER BY   column];

having子句示例
求平均工资大于2000的部门,要求显示:部门号,平均工资

select deptno,avg(sal)
from emp
group by deptno
having avg(sal) > 2000;

select count 不使用索引 select 不包含_分组函数_17


四、使用HAVING子句过滤分组结果集

1、where与having的区别

不能再WHERE子句中使用组函数(注意)

可以在HAVING子句中使用组函数

2、where与having可以通用的情况

例:查询10号部门的平均工资
注:从SQL优化的角度上看,尽量使用where;
having先分组,后过滤;where先过滤,后分组

select deptno,avg(sal)
from emp
group by deptno
having deptno=10;

select count 不使用索引 select 不包含_select count 不使用索引_18

select deptno,avg(sal)
from emp
where deptno=10
group by deptno;

select count 不使用索引 select 不包含_数据库_19


五、在分组查询中使用order by子句

例:求每个部门的平均工资,要求显示:部门号,部门的平均工资,并且按照工资升序排列

可以按照:(列、别名、表达式、序号)进行排序

select deptno,avg(sal)
from emp
group by deptno
order by avg(sal);
select deptno,avg(sal) 平均工资
from emp
group by deptno
order by 平均工资;
select deptno,avg(sal) 平均工资
from emp
group by deptno
order by 2;

select count 不使用索引 select 不包含_sql_20

1、分组函数的嵌套

例:求部门平均工资的最大值
1、通过AVG函数求出每个部门的平均工资
2、嵌套MAX函数求出部门平均工资的最大值

select max(avg(sal))
from emp
group by deptno;

select count 不使用索引 select 不包含_oracle_21

2、group by 语句的增强

(1)按部门、不同的职位,统计工资总额

select deptno,empjob,sum(sal)
from emp
group by deptno,empjob
order by deptno;

select count 不使用索引 select 不包含_数据库_22


(2)按部门,统计工资总额

select deptno,avg(sal)
from emp
group by deptno
order by deptno;

select count 不使用索引 select 不包含_sql_23


(3)统计工资总额

select sum(sal) from emp;

select count 不使用索引 select 不包含_分组函数_24


语法:

group by rollup(a, b)
等价于:
	group by a,b
	+
	group by a
	+
	group by null
select deptno,empjob,sum(sal)
from emp
group by rollup(deptno,empjob);

select count 不使用索引 select 不包含_select count 不使用索引_25

break on deptno skip 2;
select deptno,empjob,sum(sal)
from emp
group by rollup(deptno,empjob);

select count 不使用索引 select 不包含_select count 不使用索引_26

set pagesize 30;
select deptno,empjob,sum(sal)
from emp
group by rollup(deptno,empjob);

select count 不使用索引 select 不包含_select count 不使用索引_27


六、SQL*Plus的报表功能

报表包括:标题、页码、别名等。

ttitle col 15 ‘我的报表’ col 35 sql.pno col 15 表示空15列 sql.pno表示报表的页码

col deptno heading 部门号 col job heading 职位 col sum(sal) heading 工资总额
break on deptno skip 1

get E:\study\大三下\数据库应用开发\导出.sql
ttitle col 15 '我的报表' col 35 sql.pno
col deptno heading 部门号
col empjob heading 职位
col sum(sal) heading 工资总额
break on deptno skip 1;
@E:\study\大三下\数据库应用开发\导出.sql;
select deptno, empjob, sum (sal) ;
from emp
group by rollup (deptno, empjob) ;
set pagesize 10;
select deptno,empjob,sum(sal)
from emp
group by rollup(deptno,empjob);

select count 不使用索引 select 不包含_分组函数_28