-- 再将emp表与上面查询结果做内连接 -- 条件: a表的部门编号=b表的部门编号,a表的员工工资=b表的最大工资 select a.ename,b.* from emp a join (select deptno,max(sal) max_sal from emp groupby deptno) b on a.deptno=b.deptno and a.sal=b.max_sal;
第二题
题目
哪些人的薪水在部门的平均薪水之上
1 2 3 4 5 6 7 8 9 10 11 12
-- 效果 +-------+---------+ | ename | sal | +-------+---------+ | ALLEN |1600.00| | JONES |2975.00| | BLAKE |2850.00| | SCOTT |3000.00| | KING |5000.00| | FORD |3000.00| +-------+---------+ 6rowsinset (0.00 sec)
-- 再将emp表与上面查询结果做内连接 -- 条件: a表的员工工资>b表的平均工资,a表的部门编号=b表的部门编号 select a.ename,a.sal from emp a join (select deptno,avg(sal) avg_sal from emp groupby deptno) b on a.sal>b.avg_sal and a.deptno=b.deptno;
-- 先把每个部门的员工名、部门编号、员工薪资等级取出 -- 将emp表与salgrade表做内连接 mysql>select e.ename,e.deptno,s.grade from emp e join salgrade s on e.sal>=s.losal and e.sal <= s.hisal; +--------+--------+-------+ | ename | deptno | grade | +--------+--------+-------+ | SMITH |20|1| | ALLEN |30|3| | WARD |30|2| | JONES |20|4| | MARTIN |30|2| | BLAKE |30|4| | CLARK |10|4| | SCOTT |20|4| | KING |10|5| | TURNER |30|3| | ADAMS |20|1| | JAMES |30|1| | FORD |20|4| | MILLER |10|2| +--------+--------+-------+ 14rowsinset (0.00 sec)
-- 再将上表的部门编号做分组,取出部门编号与薪资平均等级 select e.deptno,avg(s.grade) from emp e join salgrade s on e.sal>=s.losal and e.sal <= s.hisal groupby e.deptno;
第四题
题目
不准用分组函数(Max),取得最高薪水(给出两种解决方案)
1 2 3 4 5 6
-- 效果 +---------+ | sal | +---------+ |5000.00| +---------+
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
-- 方法1: 对sal进行降序排序后,取第一个值 select sal from emp orderby sal desc limit 1;
-- 方法2: 对表进行自连接,获取到小于最大值的全部值,再将结果与emp表对比,不存在就拿出来 select sal from emp where sal notin (select a.sal from emp a join emp b on a.sal<b.sal);
-- 再取平均工资中的最大值 selectmax(t.avg_sal) from (select deptno,avg(sal) avg_sal from emp groupby deptno) t; +----------------+ |max(t.avg_sal) | +----------------+ |2916.666667| +----------------+
-- 再通过分组查到每个部门的平均工资,再与上面获取到的最大值进行对比 select deptno,avg(sal) avgsal from emp groupby deptno having avgsal=(selectmax(t.avg_sal) from (select deptno,avg(sal) avg_sal from emp groupby deptno) t);
-- 方法1: -- 先获取平均工资后进行降序排序,取第一个值就是最大值 -- 再使用上面结果与dept表进行内连接 select d.dname from dept d join (select e.deptno,avg(e.sal) avg_sal from emp e groupby deptno orderby avg_sal desc limit 1) t on d.deptno=t.deptno;
-- 方法2: 以部门名字分组 select d.dname,avg(e.sal) avg_sal from emp e join dept d on e.deptno=d.deptno groupby d.dname orderby avg_sal desc limit 1;
-- 方法1: -- 先获取平均工资后进行升序排序,取第一个值就是最小值 -- 再使用上面结果与dept表进行内连接 select d.dname from dept d join (select e.deptno,avg(e.sal) avg_sal from emp e groupby deptno orderby avg_sal limit 1) t on d.deptno=t.deptno;
-- 方法2: 以部门名称分组 select d.dname,avg(e.sal) avg_sal from emp e join dept d on d.deptno=e.deptno groupby d.dname orderby avg_sal limit 1;
第八题
题目
取得比普通员工(员工代码没有在 mgr 字段上出现的)的最高薪水还要高的 领导人姓名
1 2 3 4 5 6 7 8 9 10 11
-- 效果 +-------+ | ename | +-------+ | JONES | | BLAKE | | CLARK | | SCOTT | | KING | | FORD | +-------+
-- 再找出普通员工中最高薪资 (员工代码不在mgr字段出现的就是普通员工) selectmax(sal) from emp where empno notin (selectdistinct mgr from emp where mgr isnotnull); +---------+ | max_sal | +---------+ |1600.00| +---------+
-- 再将普通员工的最高薪资与领导薪资对比 select ename from emp where sal>(selectmax(sal) from emp where empno notin (selectdistinct mgr from emp where mgr isnotnull));
第九题
题目
取得薪水最高的前五名员工
1 2 3 4 5 6 7 8 9 10
-- 效果 +-------+---------+ | ename | sal | +-------+---------+ | KING |5000.00| | FORD |3000.00| | SCOTT |3000.00| | JONES |2975.00| | BLAKE |2850.00| +-------+---------+
实现
1 2
-- 按照工资降序排序后取得前五个值 select ename,sal from emp orderby sal desc limit 0,5;
第十题
题目
取得薪水最高的第六到第十名员工
1 2 3 4 5 6 7 8 9 10
-- 效果 +--------+---------+ | ename | sal | +--------+---------+ | CLARK |2450.00| | ALLEN |1600.00| | TURNER |1500.00| | MILLER |1300.00| | WARD |1250.00| +--------+---------+
实现
1 2
-- 按照工资降序排序后取得6~10的值 select ename,sal from emp orderby sal desc limit 5,5;
第十一题
题目
取得最后入职的 5 名员工
1 2 3 4 5 6 7 8 9 10
-- 效果 +--------+------------+ | ename | hiredate | +--------+------------+ | ADAMS |1987-05-23| | SCOTT |1987-04-19| | MILLER |1982-01-23| | JAMES |1981-12-03| | FORD |1981-12-03| +--------+------------+
-- 效果 +--------+--------+ | 员工 | 领导 | +--------+--------+ | SMITH | FORD | | ALLEN | BLAKE | | WARD | BLAKE | | JONES | KING | | MARTIN | BLAKE | | BLAKE | KING | | CLARK | KING | | SCOTT | JONES | | KING |NULL| | TURNER | BLAKE | | ADAMS | SCOTT | | JAMES | BLAKE | | FORD | JONES | | MILLER | CLARK | +--------+--------+ 14rowsinset (0.00 sec)
实现
1 2
-- 使用自连接,将员工的mgr与领导的empno匹配,获取到结果 select a.ename 员工,b.ename 领导 from emp a leftjoin emp b on a.mgr=b.empno;
第十五题
题目
列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称
1 2 3 4 5 6 7 8 9 10 11
-- 效果 +--------------+-----------+------------+ | 员工编号 | 员工名 | 部门 | +--------------+-----------+------------+ |7369| SMITH | RESEARCH | |7499| ALLEN | SALES | |7521| WARD | SALES | |7566| JONES | RESEARCH | |7698| BLAKE | SALES | |7782| CLARK | ACCOUNTING | +--------------+-----------+------------+
-- 获取员工与对应领导的入职时间 select a.empno 员工编号,a.hiredate 员工入职时间 ,b.ename 领导,b.hiredate 领导入职时间 from emp a join emp b on a.mgr=b.empno; +--------------+--------------------+--------+--------------------+ | 员工编号 | 员工入职时间 | 领导 | 领导入职时间 | +--------------+--------------------+--------+--------------------+ |7369|1980-12-17| FORD |1981-12-03| |7499|1981-02-20| BLAKE |1981-05-01| |7521|1981-02-22| BLAKE |1981-05-01| |7566|1981-04-02| KING |1981-11-17| |7654|1981-09-28| BLAKE |1981-05-01| |7698|1981-05-01| KING |1981-11-17| |7782|1981-06-09| KING |1981-11-17| |7788|1987-04-19| JONES |1981-04-02| |7844|1981-09-08| BLAKE |1981-05-01| |7876|1987-05-23| SCOTT |1987-04-19| |7900|1981-12-03| BLAKE |1981-05-01| |7902|1981-12-03| JONES |1981-04-02| |7934|1982-01-23| CLARK |1981-06-09| +--------------+--------------------+--------+--------------------+ 13rowsinset (0.00 sec)
-- 使用自连接将员工与对应领导的入职时间取出来 -- 再通过员工表的deptno与dept表的deptno做为内连接的条件 -- 最后将员工入职时间与领导入职时间做对比 select a.empno 员工编号,a.ename 员工名,d.dname 部门 from emp a join emp b on a.mgr=b.empno join dept d on a.deptno=d.deptno where a.hiredate<b.hiredate;
-- 效果 +------------+--------+ | dname | ename | +------------+--------+ | RESEARCH | SMITH | | SALES | ALLEN | | SALES | WARD | | RESEARCH | JONES | | SALES | MARTIN | | SALES | BLAKE | | ACCOUNTING | CLARK | | RESEARCH | SCOTT | | ACCOUNTING | KING | | SALES | TURNER | | RESEARCH | ADAMS | | SALES | JAMES | | RESEARCH | FORD | | ACCOUNTING | MILLER | | OPERATIONS |NULL| +------------+--------+ 15rowsinset (0.00 sec)
实现
1 2 3 4 5 6 7 8 9
-- 使用外连接获取,条件为部门名称相等 select d.dname,e.ename from emp e rightjoin dept d on d.deptno=e.deptno;
第十七题
题目
列出至少有 5 个员工的所有部门
1 2 3 4 5 6 7
-- 效果 +----------+-----+ | dname | num | +----------+-----+ | RESEARCH |5| | SALES |6| +----------+-----+
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
-- 先按照员工进行分组查询,将员工人数大于等于5的部门编号取出 select deptno,count(*) num from emp groupby deptno having num>=5; +--------+-----+ | deptno | num | +--------+-----+ |20|5| |30|6| +--------+-----+
-- 再将取到的表设置别名为t,再将t表与dept表做内连接 select d.dname,t.num from dept d join (select deptno,count(*) num from emp groupby deptno having num>=5) t on t.deptno=d.deptno;
第十八题
题目
列出薪金比”SMITH”多的所有员工信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
-- 效果 +-------+--------+-----------+------+------------+---------+---------+--------+ | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO | +-------+--------+-----------+------+------------+---------+---------+--------+ |7499| ALLEN | SALESMAN |7698|1981-02-20|1600.00|300.00|30| |7521| WARD | SALESMAN |7698|1981-02-22|1250.00|500.00|30| |7566| JONES | MANAGER |7839|1981-04-02|2975.00|NULL|20| |7654| MARTIN | SALESMAN |7698|1981-09-28|1250.00|1400.00|30| |7698| BLAKE | MANAGER |7839|1981-05-01|2850.00|NULL|30| |7782| CLARK | MANAGER |7839|1981-06-09|2450.00|NULL|10| |7788| SCOTT | ANALYST |7566|1987-04-19|3000.00|NULL|20| |7839| KING | PRESIDENT |NULL|1981-11-17|5000.00|NULL|10| |7844| TURNER | SALESMAN |7698|1981-09-08|1500.00|0.00|30| |7876| ADAMS | CLERK |7788|1987-05-23|1100.00|NULL|20| |7900| JAMES | CLERK |7698|1981-12-03|950.00|NULL|30| |7902| FORD | ANALYST |7566|1981-12-03|3000.00|NULL|20| |7934| MILLER | CLERK |7782|1982-01-23|1300.00|NULL|10| +-------+--------+-----------+------+------------+---------+---------+--------+ 13rowsinset (0.00 sec)
实现
1 2 3 4 5 6 7
-- 使用子查询获取到SMITH的工资,将查询结果作为where条件对比 select * from emp where sal>(select sal from emp where ename='SMITH');
第十九题
题目
列出所有”CLERK”(办事员)的姓名及其部门名称,部门的人数.
1 2 3 4 5 6 7 8 9 10
-- 效果 +--------+------------+-----+ | ename | dname | num | +--------+------------+-----+ | SMITH | RESEARCH |5| | ADAMS | RESEARCH |5| | JAMES | SALES |6| | MILLER | ACCOUNTING |3| +--------+------------+-----+ 4rowsinset (0.00 sec)
-- 先获取办事员的姓名、部门名、部门编号 -- 将emp与dept表做内连接,条件为deptno相等,再使用where设置emp表的job字段为CLERK select e.ename,d.dname,d.deptno from emp e join dept d on e.deptno=d.deptno where e.job='CLERK'; +--------+------------+--------+ | ename | dname | deptno | +--------+------------+--------+ | SMITH | RESEARCH |20| | ADAMS | RESEARCH |20| | JAMES | SALES |30| | MILLER | ACCOUNTING |10| +--------+------------+--------+
-- 再获取每个部门的人数 select deptno,count(*) num from emp groupby deptno; +--------+-----+ | deptno | num | +--------+-----+ |10|3| |20|5| |30|6| +--------+-----+
-- 再将上面两个查询结果做内连接 select t1.ename,t1.dname,t2.num from (select e.ename,d.dname,d.deptno from emp e join dept d on e.deptno=d.deptno where e.job='CLERK') t1 join (select deptno,count(*) num from emp groupby deptno) t2 on t1.deptno=t2.deptno;
-- 先获取到SALES的部门编号 select deptno from dept where dname='SALES'; +--------+ | deptno | +--------+ |30| +--------+
-- 再将上面的查询结果作为where条件 select ename from emp where deptno=(select deptno from dept where dname='SALES');
-- 或者使用内连接(不推荐) select e.ename from emp e join (select deptno from dept where dname='SALES') t on e.deptno=t.deptno;
第二二题
题目
列出薪金高于公司平均薪金的所有员工,所在部门,上级领导,雇员的工资等级
1 2 3 4 5 6 7 8 9 10 11 12
-- 效果(注意KING是没有上级领导的) +--------+------------+--------+--------+ | 员工 | 部门 | 领导 | 等级 | +--------+------------+--------+--------+ | JONES | RESEARCH | KING |4| | BLAKE | SALES | KING |4| | CLARK | ACCOUNTING | KING |4| | SCOTT | RESEARCH | JONES |4| | FORD | RESEARCH | JONES |4| | KING | ACCOUNTING |NULL|5| +--------+------------+--------+--------+ 6rowsinset (0.00 sec)
-- 先将员工与对应的部门名取出 -- 再将取出的内容与emp表做左自连接,得到员工与领导的对应信息 -- 再将取出的内容与salgrade表做薪资等级运算(左连接) -- 再使用where语句过滤大于平均薪资的员工信息 select e.ename 员工,d.dname 部门,l.ename 领导,s.grade 等级 from emp e leftjoin dept d on e.deptno=d.deptno leftjoin emp l on l.empno=e.mgr leftjoin salgrade s on e.sal >= s.losal and e.sal <= s.hisal where e.sal>(selectavg(sal) from emp);
第二三题
题目
列出与”SCOTT”从事相同工作的所有员工及部门名称
1 2 3 4 5 6 7
-- 效果 +-------+----------+ | ename | dname | +-------+----------+ | FORD | RESEARCH | +-------+----------+ 1rowinset (0.00 sec)
实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
-- 先将emp表与dept表做内连接 -- 再设置where条件为job等于SCOTT的JOB名 -- 再过滤掉SCOTT本身 select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno where e.job=(select job from emp where ename='SCOTT') and e.ename!='SCOTT';
-- 先获取到部门编号为30的工资 mysql>selectdistinct sal from emp where deptno=30; +---------+ | sal | +---------+ |1760.00| |1375.00| |3135.00| |1650.00| |1045.00| +---------+
-- 再将部门编号非30的员工姓名、工资取出,使用in来判断是否包含在里面 select ename,sal from emp where sal in (selectdistinct sal from emp where deptno=30) and deptno!=30;
第二五题
题目
列出薪金高于在部门 30 工作的所有员工的薪金的员工姓名和薪金.部门名称
1 2 3 4 5 6 7 8 9 10
-- 效果 +-------+---------+------------+ | ename | sal | dname | +-------+---------+------------+ | JONES |2975.00| RESEARCH | | SCOTT |3000.00| RESEARCH | | KING |5000.00| ACCOUNTING | | FORD |3000.00| RESEARCH | +-------+---------+------------+ 4rowsinset (0.00 sec)
-- 先算出30部门的员工最高薪资 mysql>selectmax(sal) from emp where deptno=30; +----------+ |max(sal) | +----------+ |2850.00| +----------+
-- 再将emp表与dept表做内连接 -- where条件为员工工资大于30部门的最高员工工资 select e.ename,e.sal,d.dname from emp e join dept d on e.deptno=d.deptno where e.sal>(selectmax(sal) from emp where deptno=30);
-- 将emp表与dept表做外连接,条件为deptno,再将结果以d.depeno做分组 -- 使用dept表因为有的部门没有员工,但也要显示在查询结果中 select d.deptno,count(e.ename),ifnull(avg(e.sal),0) avg_sal,ifnull(avg(timestampdiff(YEAR,e.hiredate,now())),0) avg_dete from emp e rightjoin dept d on d.deptno=e.deptno groupby d.deptno;
-- 再将上面查询结果与emp表做自连接 -- 条件为job=job and min_sal=sal select e.ename,t.* from emp e join (select job,min(sal) min_sal from emp groupby job) t on e.job=t.job and e.sal=t.min_sal;
-- 效果 +--------+----------+ | ename | sal | +--------+----------+ | SMITH |9600.00| | JAMES |11400.00| | ADAMS |13200.00| | WARD |15000.00| | MARTIN |15000.00| | MILLER |15600.00| | TURNER |18000.00| | ALLEN |19200.00| | CLARK |29400.00| | BLAKE |34200.00| | JONES |35700.00| | SCOTT |36000.00| | FORD |36000.00| | KING |60000.00| +--------+----------+ 14rowsinset (0.00 sec)
实现
1 2 3 4 5 6 7
-- 将工资*12,再进行排序 select ename,sal*12 sal from emp orderby sal;
第三二题
题目
求出员工领导的薪水超过 3000 的员工名称与领导名称
1 2 3 4 5 6 7 8 9
-- 效果 +--------+--------+ | 员工 | 领导 | +--------+--------+ | JONES | KING | | BLAKE | KING | | CLARK | KING | +--------+--------+ 3rowsinset (0.00 sec)
实现
1 2 3 4 5 6 7 8 9 10 11 12
-- 使用自连接查出员工与领导的关系 -- 再找出工资大于3000的领导 select a.ename 员工,b.ename 领导,b.sal from emp a join emp b on a.mgr=b.empno where b.sal>3000;
-- 先查出与员工对应的部门名 -- 再过滤出包含S的部门 -- 再对部门进行分组 select d.dname,sum(sal),count(e.ename) from emp e rightjoin dept d on e.deptno=d.deptno where d.dname like "%S%" groupby d.dname;