学习资料

学习的笔记


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