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;
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;
聚合函数(又称为分组函数,多行函数,集合函数),用于统计。
作用是对结果集的某些字段进行统计然后得出一个结果。
求给定字段的最大值和最小值
--查看公司的最高工资与最低工资? select max(sal),min(sal) from emp;
SUM()求和函数、AVG()求平均值
--查看公司的平均工资与工资总和? select avg(sal),sum(sal) from emp;
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;
"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;
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;
--查看每个部门的平均工资,前提是该部门的平均工资>2000 select avg(sal),deptno from emp where avg(sal)>2000 group by deptno;--!!!此处不允许使用分组函数,因为WHERE条件过滤的时机不对
在WHERE
子句中不能使用聚合函数作为过滤条件,原因是过滤的时机不对,WHERE
是在数据库检索表中数据时,对数据逐条过滤以决定是否查询出该
数据时使用的,所以使用WHERE来确定结果集的数据。
使用聚合函数的结果作为过滤条件,那么一定是数据从表中查询完毕(WHERE在查询
过程中发挥作用)得到结果集,并且分组完毕才进行聚合函数统计结果,得到以后才可以对
分组进行过滤,由此可见,这个过滤时机是在WHERE
之后进行的。
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;