Oracle里的多行函数也组函数,例如AVG, COUNT, MAX, MIN, SUM操作的是一组数据,返回一个结果。
求和函数SUM
sum() 可以对指定列的各行求和
select sun(sal) from emp; --将sal列里的数值全部相加
非空行函数 COUNT
count() 函数可以统计指定列的非空行数、如果要求不重复的个数,使用distinct。
select count(*) from emp; select count(distinct job) from emp; --重复的行 只取一次
求平均数函数 AVG
select avg(sal) from emp;
求员工的平均奖金:
SQL> select sum(comm)/count(*) 方式一, sum(comm)/count(comm) 方式二, avg(comm) 方式三 from emp;
结果:方式一结果不同,方式二 和 方式三结果一样。
☆NULL空值:组函数都有自动滤空功能(忽略空值),所以:
SQL> select count(*), count(comm) from emp; 执行结果不相同。
如何屏蔽 组函数 的滤空功能:
SQL> select count(*), count(nvl(comm,0)) from emp;
但是实际应用中,结果为14和结果为4都有可能对,看问题本身是否要求统计空值。
分组数据
group by 、按照group by 后给出的表达式,将from后面的table进行分组,针对每一个组使用组函数
比如查询公司里 “部门”的平均工资:
SELECT deptno, avg(sal)FROM emp GROUP BY deptno; --可以抽象成:select a, 组函数(x) from 表 group by a; 这样的格式。
注意:所有没有包含在组函数中的列,都必须在group by的后面出现。所以 select a, b 组函数(x) …… group by 应该写成group by a, b;没有b语法就会出错,不会执行SQL语句。但,反之可以。Group by a,b,c; c可以不出现在select语句中。
由于语法规定group by后面 就会出现有多列的情况,例如这条SQL语句:
select deptno, job, avg(sal) from emp group by deptno, job order by 1;
该SQL的语义:按部门,不同的职位统计平均工资。先按第一列分组,如果第一列相同,再按第二列分组。所以查询结果中,同一部门中没有重复的职位
使用group by的时候还需要注意的一点的是 ,where子句中不能使用“组函数”。可以使用 Having来过滤分组。
比如查找出平均薪水大于2000的部门, sql语句如下:
SELECT deptno, avg(sal) FROM emp GROUP BY deptno having avg(sal)>2000;
从功能上讲,where还having都可以将满足条件的结果过滤处理来,但是语法规定 where子句中不能使用“组函数” 所以上句中的having不可以使用where代替。
如果只是单纯的求某个部门的平均工资,那么使用where和having都可以(因为子句中没有使用组函数),这种情况下 我们应该优先使用 where 。因为如果有分组的话,where是先过滤再分组,而having是先分组再过滤。当数据量庞大如1亿条,where优势明显。