MySQL 练习题

基于之前的三张表

1. 取得每个部门最高薪水的人员名称

  取得每个部门最高薪水,和emp表做连接查询

select t.*,e.ename from emp e join (select deptno,max(sal) maxsal from emp group by deptno) t on t.deptno = e.deptno and t.maxsal = e.sal;

2. 哪些人的薪水在部门平均薪水之上

  先取得部门平均薪水,之后作为t表,和emp做连接查询

select e.ename,e.sal from emp e join (select deptno,avg(sal) avgsal from emp group by deptno) t on e.sal > t.avgsal and e.deptno = t.deptno;

3. 取得部门中(所有人的)平均薪水等级

  每个人的薪水等级,然后按照部门分组,求等级的平均值

select e.deptno,avg(s.grade) from emp e join salgrade s on e.sal between s.losal and s.hisal group by deptno order by deptno;

4. 不使用组函数(max)取得最高薪水

select sal from emp order by sal desc limit 0,1;

5. 取得平均薪水最高的部门的部门编号

  先取得部门的平均薪水,然后做降序后,取第一个

select deptno,avg(sal) as avgsal from emp group by deptno order by avg(sal) desc limit 0,1;

6. 取得平均薪水最高的部门的部门名称

  先取得部门的平均薪水降序,然后与dept表做连接查询取第一个

select e.deptno,d.dname,avg(e.sal) as avgsal from emp e join dept d on d.deptno = e.deptno group by deptno order by avgsal desc limit 0,1;

7. 求平均薪水的等级最低的部门的部门名称
  三张表做连接查询,先取得部门的平均薪水,然后与等级表做连接查询,然后再与部门名称表做连接查询

select d.dname from (select deptno,avg(sal) as avgsal from emp group by deptno) t join salgrade s on t.avgsal between s.losal and s.hisal join dept d on d.deptno = t.deptno limit 0,1;

8. 取得比普通员工(员工代码没有再mgr字段上出现)的最高薪水还要高的领导人的姓名

  先找到普通员工(即员工编号不在mgr中出现的就是普通员工),然后找到普通员工的最高工资,比普通员工的最高工资高的肯定是领导

select ename,sal from emp where sal > (select max(sal) from emp where empno not in (select distinct mgr from emp where mgr is not null))

9. 取得薪水最高的前五名员工

select ename,sal from emp order by sal desc limit 0,5;

10. 取得薪水最高的第六到第十名员工

  薪水相同,ename 升序

select ename,sal from emp order by sal desc,ename asc limit 5,5;

11. 取得最后入职的5名员工

select ename,hiredate from emp order by hiredate desc,ename asc limit 0,5;

12. 取得每个薪水等级有多少员工

  先求每个员工的薪资等级,然后按照薪资等级分组求总数,排序

select s.grade,count(*) from emp e join salgrade s on e.sal between s.losal and s.hisal group by s.grade order by s.grade;

13. 有3个表S(学生表),C(课程表),SC(学生选课表) 

  S(SNO,SNAME)代表(学号,姓名)
  C(CNO,CNAME,CTEACHER)代表(课号,课名,教师)
  SC(SNO,CNO,SCGRADE)代表(学号,课号,成绩)

     

   (1)找出没有选过‘黎明’老师的所有学生的姓名

select * from s where sno not in (select sno from sc where cno = 5);

  (2)列出2门以上(含2门)不及格学生姓名及平均成绩

   先求出两门以上不及格的学生作为b表,求出每个学生的平均成绩作为c表,三张表做连接查询

select a.sname,c.avgscgrade from (select sno from sc where scgrade < 60 group by sno having count(scgrade) >= 2) b join s a on b.sno = a.sno join (select sno,avg(scgrade) as avgscgrade from sc group by sno) c on a.sno = c.sno;

  (3)即学过1号课程又学过2号课程的所有学生的姓名

  先求出即学过1号课程又学过2号课程的学生(即选过1号或2号并且选课的数量大于等于2)作为b表和s表连接查询

select s.sname,s.sno from s join (select sno from sc where cno in (1,2) group by sno having count(cno) >= 2) b on s.sno = b.sno;

14. 列出所有员工及领导的姓名
  左外连接,左边为主表,右边没有补空

select a.ename,ifnull(m.ename,'没有上级') from emp a left join emp m on a.mgr = m.empno;

15. 列出受雇日期早于直接上级的所有员工的编号,姓名,部门名称

  先求受雇日期早于其直接上级的所有员工,然后和dept表做连接查询

select a.empno,a.ename,d.dname from emp a left join emp m on a.mgr = m.empno join dept d on a.deptno = d.deptno where a.hiredate < m.hiredate;

16. 列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门

  左外连接

select d.dname,e.* from dept d left join emp e on d.deptno = e.deptno;

17. 列出至少有5个员工的所有部门

  以部门编号分组,求出每个部门员工的数量,然后再having过滤出大于5个的

select d.dname,count(*) from dept d left join emp e on d.deptno = e.deptno group by d.dname having count(*) >= 5;

18. 列出薪金比“SMITH”多的员工信息

select * from emp where sal > (select sal from emp where ename = 'smith');

19. 列出所有“CLERK”的姓名及部门名称,部门人数

  先求出工作时clerk的员工和部门名称作为a表,按照部门号分组求出部门编号和每个部门的人数作为b表,a表和b表做连接查询

select a.ename,a.dname,b.cc from (select e.ename,d.dname,d.deptno from emp e join dept d on e.deptno = d.deptno where job = 'clerk') a join (select e.deptno,count(*) as cc from emp e group by e.deptno) b on a.deptno = b.deptno;

20. 列出最低薪金大于1500的各种工作及从事此工作的全部雇员人数

    先求出最低薪资大于1500的工作岗位作为a表,求出各个岗位的全部雇员数作为b表,两张表做连接查询

select job,count(*) from emp group by job having min(sal) > 1500;

21. 列出所在部门"sales"<销售部>工作的员工姓名,假定不知道销售部的部门编号;

  先查出部门编号,在子查询

select ename from emp where deptno = (select deptno from dept where dname = 'sales');

22. 列出薪金高于公司平均薪金的所有员工,所在部门,上级领导,雇员的工资等级

  先求出薪资高于平均薪资的所有员工,然后和dept表连接查询求部门名称,和emp表连接求上级领导,和salgrade表连接求工资等级

select e.ename,d.dname,f.ename,s.grade from emp e join dept d on d.deptno = e.deptno left join emp f on e.mgr = f.empno join salgrade s on e.sal between s.losal and s.hisal where e.sal > (select avg(sal) from emp);

23. 列出与“scott”从事相同工作的所有员工及部门名称

  先找到scott的工作岗位,然后连接查询

select e.ename,d.dname from emp e join dept d on e.deptno = d.deptno where job = (select job from emp where ename = 'scott') and e.ename <> 'scott';

24. 列出薪金等于部门30中员工的薪金的其他员工的姓名和薪金;

  先求出部门30的所有薪金,然后在emp表中查询满足条件的其他员工

select ename,sal from emp where sal in (select distinct sal from emp where deptno = 30) and deptno <> 30;

25. 列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金,部门名称。
  先求出部门30的最高工资,然后与dept表连接查询

select e.ename,e.sal,d.dname from emp e join dept d on e.deptno = d.deptno where sal > (select max(sal) from emp where deptno = 30);

26. 列出每个部门工作的员工数量,平均工资和平均服务期限
  平均服务期限,计算时间函数timestampdiff(间隔类型,前一个时间,后一个时间)

select d.dname,count(*),avg(sal),avg(timestampdiff(YEAR,hiredate,now())) from emp e join dept d on e.deptno = d.deptno group by e.deptno;

27. 列出所有员工的姓名,部门名称和工资
  emp表和dept表做连接查询

select e.ename,d.dname,e.sal from emp e join dept d on e.deptno = d.deptno order by d.dname;

28. 列出所有部门的详细信息和人数
  dept和emp表做左外连接查询,按照e.deptno分组

select d.*,count(e.deptno) as '人数' from dept d left join emp e on d.deptno = e.deptno group by e.deptno;

29. 列出各种工作的最低工资及从事此工作的雇员姓名
  先求出各个岗位的最低工资作为a表,和emp表做连接查询,查询条件是工资相等

select e.* from emp e join (select job,min(sal) as minsal from emp group by job) a on a.minsal = e.sal and a.job = e.job;

30. 列出各个部门的manager领导的最低工资

select deptno,min(sal) from emp where job = 'manager' group by deptno;

31. 列出所有员工的年工资,按照年薪从低到高排序
  ifnull(comm,0) 如果comm为空就当作

select ename,(sal + ifnull(comm,0))*12 as incomm from emp order by incomm;

32. 求出员工领导的薪水超过3000的员工名称和领导名称
  自连接求出每个员工的领导,条件查询领导薪水超过3000的

select a.ename,b.ename from emp a join emp b on a.mgr = b.empno where b.sal > 3000;

33. 求出部门名称中带'S'字符的部门员工的工资合计,部门人数
  对emp表和dept表做右连接查询,按照部门名分组,条件是部门名中带有'S';

select d.dname,count(e.ename),sum(sal) from emp e right join dept d on e.deptno = d.deptno where d.dname like '%S%' group by d.dname;

34. 给任职日期超过30年的员工加薪10%;

update emp set sal = sal * 1.1 where timestampdiff(YEAR,hiredate,now()) > 30;
原文地址:https://www.cnblogs.com/homle/p/15058657.html