ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

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

2022-06-08 08:00:08  阅读:220  来源: 互联网

标签:语句 sal -- 分组 emp 子句 Oracle deptno select


一、排序

(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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有