目录
第四题:不准用max()函数,取得最高工资,用两种方案进行解决
第八题:取得比普通员工(员工的empno没有在mgr字段上出现过的为普通员工)的最高薪水还要高的领导人的姓名
引言
正文:该部分练习题主要运用的表有以下几个:
(一):emp是员工表
EMPNO 员工编号 ENAME 员工姓名 JOB 工作岗位 MGR 上级编号
HIREDATE 入职日期 SAL 工资 COMM 补助 DEPTNO 部门编号
(二):dept是部门表
DEPTNO 部门编号 DNAME 部门名字 LOC 地理位置
(三):salgrade 是工资等级
GRADE 工资等级 LOSAL 最低工资 HISAL 最高工资
分析:先把部分进行分组,查询出每个部门工资最高的信息作为临时表t1,然后与emp进行连接,筛选出部门相等并且是与t1表中的薪资也相等的信息。
语句为:mysql> select e.ename,e.sal,e.deptno from emp e join (select deptno,max(sal) as maxsal from emp group by deptno) t1
-> on e.deptno=t1.deptno and e.sal=t1.maxsal;
结果为:
分析:这道题还是要先按照部门进行分组,然后查出各个部门的平均薪资需要用avg函数,然后和emp表进行连接,筛选出来满足部门相等,并且工资大于等于各个部门的平均薪资
语句为: select e.ename,e.sal,e.deptno from emp e join (select deptno,avg(sal) as avgsal from emp group by deptno) t1
-> on e.deptno=t1.deptno and e.sal>=t1.avgsal;
结果为:
分析:工资等级是对应于salgrade这张表,各个部门员工的平均工资可以用emp这张表来实现。首先将部门进行分组,然后取得各个部门的平均薪资,将得到的表作为t1,然后和salgrade这张表进行连接,查询出平均工资所在的薪资等级在哪一个区间,然后输出部门名,输出薪资,输出所属等级。
语句为:select t2.dname,t2.avgsal,grade from salgrade join (select d.dname,t1.avgsal from dept d join (select deptno,avg(sal) avgsal from emp group by deptno) t1 on d.deptno=t1.deptno) t2 on avgsal between losal and hisal;
结果为:
分析:取得最高工资,可以用升序,然后限制输出一条工资信息即可
另一种方案是让emp表进行自连接,自连接的条件是,a.emp<b.emp;这样子能够保证除了最高工资以外的信息都能够被查出来,为了避免信息重复显示,可以使用distinct;然后查出来的信息作为一个新表t,再从emp表中筛选,不在t中的数据就是最高的工资那条数据。
语句为:方案一:select sal from emp order by sal desc limit 1;
方案二:select sal from emp where sal not in(select distinct e.sal from emp e join emp b on e.sal<b.sal);
结果为:
分析:先对部门进行分组,然后计算各个部门的平均薪资,然后排序找到最大的那个,或者是用max函数找出平均值最大的即可
第一种方案需要用到limit,group by,order by,是一种综合的语句运用练习题,语句为:
select t.deptno from (select deptno,avg(sal) avgsal from emp group by deptno order by avgsal desc limit 1) t;
第二种方案需分布进行,首先查询出各个部门的平均工资作为临时表t,然后从这这表中找出最大值max(avgsal),然后呢,再从t表中查找等于最大值max(avgsal)的信息deptno即可,其语句为:
create table t select deptno,avg(sal) avgsal from emp group by deptno;
select deptno from t where avgsal=(select max(avgsal) maxavgsal from t);
结果为:
分析:先按照部门进行分组,然后计算出各个部门的平均工资,然后进行降序排序,查找出第一条记录就是平均工资最高的那一条,然后和dept这张表进行连接,查找出deptno相等的那个记录的dname就可以了。
语句为:select d.dname,s.deptno from dept d join (select t.deptno from (select deptno,avg(sal) avgsal from emp group by deptno order by avgsal desc limit 1) t) s on s.deptno=d.deptno;
结果为:
分析:这道题和第六题有点相似,这里只不过是按照升序排序asc即可,然后取出第一条记录作为表t,然后和dept这张表连接,筛选出deptno相等的即可。
语句为:select t.deptno,d.dname from dept d join (select deptno,avg(sal) avgsal from emp group by deptno order by avgsal asc limit 1) t on t.deptno=d.deptno;
结果为:
分析:第一步要先找出在mgr字段出现的empno的姓名,然后把这个表t查出来,接着查询empno不在这张表t中的员工的信息,及普通员工的信息,然后找出员工中的最高工资进行筛选即可。
语句为:select ename,sal from emp where sal>(select max(sal) maxsal from emp where empno not in(select distinct mgr from emp where mgr is not null));
结果为:
分析:本题较为简单,只需要按照工资进行排序,然后输出前五条即可
语句为:select ename,sal from emp order by sal desc limit 0,5;
结果为:
分析:当查询出来的信息为某部分是,需要用到limit来查找,其后面可以跟两个参数,第一个参数代表起始位置start,起始位置下表默认从0开始,第二个参数代表查询的长度。
语句为:select ename,sal from emp order by sal desc limit 5,5;
结果为:
分析:hiredate这个字段的信息是年月日,其年月日也可以按照降序进行排序,然后limit取出前五个字段的信息即可。
语句为:select ename,hiredate from emp order by hiredate desc limit 5;
结果为:
分析:第一步将emp表和salgrade薪资等级表进行连接,查找出每一名员工所属的信息等级范围,用between and即可,然后将查询出来的表按照等级grade进行分组,使用函数count查询出每一个工资等级有多少人就可以了。
语句为:select t.grade,count(t.ename) from (select e.ename,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal) t group by t.grade order by t.grade;
结果为:
总结:以上就是关于emp,dept,salgrade这三张表的连接或者是自连接的综合运用,其问题的实现需要运用到的东西基本上涵盖了所学mysql的最主要的知识。
这里附录上所需要运用到的数据库,该数据库中有三张表,emp,dept,salgrade。
链接:https://pan.baidu.com/s/1AsA8sNDn3bHptMwX4Xle1Q
提取码:llbs
下一篇练习题是关于学生表,课程表,学生选课表的综合运用,包括表的创建,表的查询。
有问题的话欢迎交流哈。