数据库
首页 > 数据库> > Oracle基础(九):排序、聚合函数、分组、查询语句的执行顺序

Oracle基础(九):排序、聚合函数、分组、查询语句的执行顺序

作者:互联网

一、排序

(1)排序结果集

ORDER BY 子句用来对结果集按照指定的字段排序,排序有两种方式:
ASC(升序):不写默认就是升序,从小到大。
DESC(降序):从大到小,需要单独指定。

ORDER BY 子句必须写在SELECT的最后一个子句上!(DQL:数据查询语言->SELECT)

--查询员工信息按工资升序排
select ename,sal from emp order by sal;--默认升序ASC
select ename,sal from emp order by sal asc;

--查询员工信息按工资降序排
select ename,sal from emp order by sal desc;

(2)多个字段排序

ORDER BY 按照多个字段排序:
ORDER BY 首先按照第一个字段的排序方式对结果集进行排序,当第一个字段有重复值时才会按照第二个字段排序方式进行排序,每个字段都可以单独指定排序方式。

select ename,deptno,sal from emp order by deptno,sal asc;--先是deptno字段排序再sal字段排序,deptno有重复时再按照sal排序
select ename,deptno,sal from emp order by deptno desc,sal;--部门号降序,工资降序

--排序中NULL值被视作为最大值,升序时排列在后,降序时排在最前
select ename,comm from emp order by comm desc;

二、聚合函数

聚合函数(又称为分组函数,多行函数,集合函数),用于统计。
作用是对结果集的某些字段进行统计然后得出一个结果。

(1)MAX()、MIN()

求给定字段的最大值和最小值

--查看公司的最高工资与最低工资?
select max(sal),min(sal) from emp;

(2)SUM()、AVG()

SUM()求和函数、AVG()求平均值

--查看公司的平均工资与工资总和?
select avg(sal),sum(sal) from emp;

(3)COUNT()

COUNT()函数,是只对字段值不为NULL的记录进行统计,返回记录条数。 忽略NULL值

注意:实际上所有的聚合函数都忽略NULL值统计。

--查看公司有多少人?
select count(ename) from emp;--返回14

SELECT COUNT(comm) FROM emp;--返回4,忽略了字段值是NULL的记录
select count(nvl(comm,0)) from emp;--使用NVL()函数将NULL值的字段值替换成非NULL值

--通常查看表的记录数可以使用COUNT(*)
select count(*) from emp;

--查看绩效的平均值、总和
select avg(comm),sum(comm) from emp;

--求平均绩效,emp表中列comm有NULL值的记录被忽略,比较两个语句结果有什么不一样...?
SELECT AVG(NVL(comm,0)),SUM(NVL(comm,0)) FROM emp;

三、分组

(1)GROUP BY子句


"GROUP BY 字段名"可以将结果集按照给定的字段值一样的记录进行分组,
配合聚合函数可以对不同的分组分别统计结果,进行更细分的统计工作。 

①当希望得到每个部门的平均薪水,而不是整个机构的平均薪水。
②把整个数据表按部门划分成一个个小组,每个小组中包含一行或多行数据, 在每个小组中再使用分组函数进行计算,每组返回一个结果。
③划分的小组有多少,最终的结果集行数就有多少。
(在SELECT当中,只要出现了聚合函数,凡是不在聚合函数当中的这些字段,都必须写在GROUP BY后面,否则出现:不是单组分组函数)
即:使用了分组后,在select语句中只允许出现分组字段和多行函数

--查看每个部门的平均工资(将数据表按部门划分为一个个小组,按部门获取平均薪资,每组返回一个结果)
select avg(sal),deptno from emp group by deptno;
select avg(sal),deptno from emp group by deptno order by deptno desc;
select avg(sal),deptno from emp group by deptno order by avg(sal) desc;

 (2)GROUP BY多字段分组

GROUP BY 也可以根据多个字段分组,分组的原则为这些字段的值都相同的记录看作一组。

SELECT avg(sal),deptno,job FROM emp GROUP BY deptno,job order by deptno,job;

SELECT deptno,job FROM emp GROUP BY deptno,job;--不使用分组函数单独写GROUP BY没什么意义,作用就相当于去重

注意:当SELECT子句中含有聚合函数时,那么凡不在聚合函数中的其他单独字段都必须出现在GROUP BY 子句中,反过来则不是必须的。 

 

select avg(sal),deptno,job from emp;--!!!不是单组分组函数
SELECT AVG(sal) FROM emp GROUP BY deptno,job;

 (3)分组中需要注意的问题

--查看每个部门的平均工资,前提是该部门的平均工资>2000
select avg(sal),deptno 
from emp 
where avg(sal)>2000 group by deptno;--!!!此处不允许使用分组函数,因为WHERE条件过滤的时机不对

WHERE子句中不能使用聚合函数作为过滤条件,原因是过滤的时机不对,
WHERE是在数据库检索表中数据时,对数据逐条过滤以决定是否查询出该
数据时使用的,所以使用WHERE来确定结果集的数据。

使用聚合函数的结果作为过滤条件,那么一定是数据从表中查询完毕(WHERE在查询
过程中发挥作用)得到结果集,并且分组完毕才进行聚合函数统计结果,得到以后才可以对
分组进行过滤,由此可见,这个过滤时机是在WHERE之后进行的。

 (4)HAVING子句

HAVING子句是用来过滤分组的。

聚合函数的过滤条件要在HAVING子句中使用,HAVING子句必须跟在 GROUP BY 子句之后,
不能单独使用,HAVING子句的作用是添加过滤条件来过滤 GROUP BY分组的,
它可以将不满足条件的分组去除。HAVING子句可以使用聚合函数作为过滤条件。
--(WHERE过滤结确定果集后,进行GROUP BY分组,然后使用HAVING来过滤分组)

--查看每个部门的平均工资,前提是该部门的平均工资>2000
--(1.先按照指定字段分组,2.然后使用HAVING子句添加条件来过滤分组)
select avg(sal),deptno from emp group by deptno having avg(sal)>2000;

--查看平均工资高于2000的部门的最高工资和最低工资分别是多少?
select max(sal),min(sal),deptno from emp
group by deptno having avg(sal)>2000;

--查看最低工资高于1000的那些职位的平均工资
select avg(sal),job
from emp
group by job having min(sal)>1000;

四、查询语句执行顺序

查询语句的执行顺序依下列子句次序
1.FROM子句:执行顺序为从后往前,从右到左(数据量较小的表尽量放在后面)
2.WHERE子句:执行顺序为自下而上、从左到右(将能过滤掉最大数量记录的条件写在WHERE子句的最右)
3.GROUP BY子句:执行顺序从左往右分组(最好在GROUP BY前使用WHERE将不需要的记录在GROUP BY之前过滤掉)
4.HAVING子句:消耗资源(尽量避免使用,HAVING会在检索出所有记录之后才对结果集进行过滤,需要排序等操作)
5.SELECT子句:少用*号,尽量取字段名称(ORACLE在解析过程中,通过查询数据字典将*号依次转换成所有列名,消耗时间)
6.ORDER BY子句:执行顺序为从左到右排序,消耗资源 

例如:
SELECT MAX(sal),MIN(sal),deptno
FROM emp
WHERE xxx>xxx
GROUP BY deptno
HAVING AVG(sal)>2000
ORDER BY XXX;

标签:语句,sal,--,分组,emp,子句,Oracle,deptno,select
来源: https://www.cnblogs.com/codercat/p/16354166.html