学习资料
李兴华老师
oracle实战
用到的表及其他
5单行函数
6多表查询
7分组统计查询
8子查询
9更新及事务处理
10替代变量
11表的创建与管理
12完整性约束
13其他数据库对象
14用户权限及角色管理
15数据库设计
系统的数据字典
oracle编码问题
何明老师
老男孩老师
Oracle专家课程系列
工具使用系列
其他oracle相关书
Oracle 高可用性
数据库监控
Oracle高可用性
SQL Server
备份与恢复相关知识
可插拨数据库CDB

学习资料

学习的笔记


7分组统计查询

<h3>学习内容</h3> <h4>统计函数</h4> <p>*<em>在开发过程中需要特别注意count(</em>)无值是返回0的**</p> <pre><code>/* count(*):该列的总记录数 sum(列):该列(数字)总和 avg(列):平均值 max(列):最大值 min(列):最小值 以上五个函数常用,以下三个函数不常用 median(列):返回中间值 variance(列):返回方差 stddev(列):返回标准差 having子句 group by 分组子句 */ --查出月工资总和 SELECT SUM(sal) 月工资总和 FROM emp ; SELECT MAX(sal) 最高工资,MIN(sal) 最低工资,AVG(sal) 平均工资,ROUND(AVG(sal),2) 平均工资两位小数 FROM emp ; SELECT MIN(hiredate) 最早雇佣 ,MAX(hiredate) 最晚雇佣 FROM emp ; SELECT MEDIAN(sal) 中间工资 FROM emp ; SELECT VARIANCE(sal) 工资方差,STDDEV(sal) 工资标准差 FROM emp ; SELECT COUNT(*),COUNT(deptno),COUNT(empno) FROM emp;--由此例可以看出null值不统计 SELECT COUNT(*),COUNT(ename),COUNT(comm),COUNT(job),COUNT(DISTINCT job) FROM emp ;--null值不统计,distinct去除重复值 select COUNT(*),MAX(sal),MIN(comm),AVG(sal),SUM(sal) FROM bonus ;--count()函数即使无值也会返加0</code></pre> <h4>单字段分组统计</h4> <pre><code>-- 分组的前提是:同一列存在重复的信息。不重复也可以分组,但是没意义。 SELECT deptno,COUNT(*) FROM emp GROUP BY deptno ; SELECT job,MAX(sal),MIN(sal) FROM emp GROUP BY job; SELECT deptno,COUNT(*) FROM emp ;--会报错。因为没有group by 的时候使用聚合函数,不能与其他字段一起使用 SELECT deptno,ename,COUNT(*) FROM emp GROUP BY deptno;--会报错。有group by的时候可以出现聚合函数和group by 后面指定的字段 --聚合函数可以嵌套使用,嵌套使用后select后再也不能出现任何的字段。取出平均工资最高的部门。 SELECT MAX(AVG(sal)) FROM emp GROUP BY deptno ;--再有其他字段就会报错 -- 什么时候使用分组 /* 当需要使用聚合函数的同时,又要显示其他列。 当一列中存在很多重复值的时候 */ -- 查询部门名称、部门人数、部门平均工资\平均服务年限。注意:需要查询的列要作为分组的条码。 SELECT d.dname 部门名称,COUNT(e.empno) 部门人数,ROUND(AVG(e.sal),2) 部门平均工资,ROUND(AVG(months_between(SYSDATE,e.hiredate)/12),2) 平均服务年限 FROM emp e FULL JOIN dept d ON e.deptno=d.deptno GROUP BY d.dname ; SELECT d.dname,COUNT(e.empno),ROUND(AVG(e.sal),2) avgsal,ROUND(AVG(months_between(SYSDATE,e.hiredate)/12),2) avgyear FROM dept d,emp e WHERE e.deptno(+)=d.deptno GROUP BY d.dname -- 查询公司各个工资等级雇员的数量、平均工资。对联合表的有重复值的列进行分组 SELECT s.grade, COUNT(*),AVG(sal) FROM emp e JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal GROUP BY s.grade -- 统计出领取佣金与不领取佣金的雇员的平均工资、平均雇佣年限、雇员人数。直接分组不能实现,所以使用union SELECT comm,round(AVG(sal),2),COUNT(*), ROUND(AVG(months_between(SYSDATE,hiredate)/12),2) FROM emp GROUP BY comm ;--直接对comm分组,comm值各不相同的为一组 SELECT '不领取奖金',round(AVG(sal),2) 平均工资,COUNT(*) 雇员人数, ROUND(AVG(months_between(SYSDATE,hiredate)/12),2) 平均年限 FROM emp WHERE comm IS NULL UNION SELECT '领取奖金',round(AVG(sal),2) 平均工资,COUNT(*) 雇员人数, ROUND(AVG(months_between(SYSDATE,hiredate)/12),2) 平均年限 FROM emp WHERE comm IS NOT NULL ;</code></pre> <h4>多字段分组统计:可以查询到更多的字段,在分组语句中,需要出现在查询字段里的列一定要出现在分组条码里</h4> <pre><code>-- 查询每个部门详细信息。 SELECT d.deptno 部门编号,d.dname 部门名称,d.loc 部门地址,COUNT(e.empno) 部门人数,NVL(ROUND(AVG(sal),2),0) 平均工资,nvl(SUM(sal),0) 总工资,nvl(MAX(sal),0) 最高工资,nvl(MIN(sal),0) 最低工资 FROM emp e RIGHT JOIN dept d ON e.deptno=d.deptno GROUP BY d.deptno,d.dname,d.loc ;</code></pre> <h4>HAVING 子句:对分给语句数据进行过滤,类似where。</h4> <pre><code>--查询出所有平均工资大于2000元的职位信息、平均工资、雇员工数。 SELECT job,ROUND(AVG(sal),2) 平均工资,COUNT(empno) 人数 FROM emp GROUP BY job HAVING AVG(sal) &gt;2000 ; SELECT d.deptno 部门编号,d.dname 部门名称,COUNT(e.ename) 部门人数, ROUND(AVG(e.sal),2) 平均工资,ROUND(MIN(e.sal),2) 最低工资,ROUND(MAX(e.sal),2) 最高工次 FROM emp e RIGHT JOIN dept d ON e.deptno = d.deptno GROUP BY d.deptno,d.dname HAVING COUNT(e.empno)&gt;1; --什么时候用where,什么时候用having:有group by才能用having,where是分组前使用,having是分组后使用。 --工作不是SALESMAN,并且同类工作工资总和大于五千的岗位,升序 SELECT job,SUM(sal) FROM emp WHERE job &lt;&gt; 'SALESMAN' GROUP BY job HAVING SUM(sal)&gt;5000 ORDER BY SUM(sal) ASC -- SALESMAN</code></pre>

页面列表

ITEM_HTML