MySQL34道练习题

1、取得每个部门最高薪水的人员名称(要求显示部门编号、人员名称和薪资)

第一步:查询每个部门的最高薪资

SELECT

        deptno,max(sal) as maxsal         

FROM

        emp

GROUP BY

        deptno;

        MySQL34道练习题_第1张图片

第二步:把上面查询结果当做临时表t,和emp e表做连接查询,条件:t.deptno = e.deptno and t.maxsal = e.sal

SELECT

        e.deptno,e.ename,e.sal

FROM

        (SELECT deptno,max(sal) as maxsal FROM emp GROUP BY deptno) t

JOIN

        emp e

ON

        t.deptno = e.deptno and t.maxsal = e.sal;

        MySQL34道练习题_第2张图片

2、哪些人的薪水在部门的平均薪水之上,要求显示员工姓名、员工薪水和部门编号和部门平均薪水

第一步:查询部门平均薪水

SELECT deptno,avg(sal) as avgsal FROM emp GROUP BY deptno;

        MySQL34道练习题_第3张图片 

第二步:将上表作为临时表t ,与emp as e表做连接查询,   条件:t.deptno = e.deptno and e.sal > t.avgsal

SELECT

        e.deptno,e.ename,e.sal,t.avgsal

FROM

        (SELECT deptno,avg(sal) as avgsal FROM emp GROUP BY deptno) t

JOIN

        emp e

ON

        t.deptno = e.deptno and e.sal > t.avgsal;

        MySQL34道练习题_第4张图片

3、取得部门中(所有人的)平均的薪水等级(显示部门编号和薪水等级的平均数)

分析:本题是"平均的薪水等级"。应该是先查询薪水等级,再计算等级的平均值。

      如果是计算"平均薪水的等级"。应该是先计算平均薪水,然后查看平均薪水的等级

第一步:查询(所有人)的薪水等级

SELECT

        e.deptno,s.grade

FROM

        emp e

JOIN

        salgrade s

ON

        e.sal between losal and hisal;

        MySQL34道练习题_第5张图片 

分析:对上面的查询直接进行分组, 求grade的平均值

SELECT

        e.deptno,avg(grade)

FROM

        emp e

JOIN

        salgrade s

ON

        e.sal between losal and hisal

GROUP BY

        e.deptno;

         MySQL34道练习题_第6张图片

4、不准用分组函数(Max() ),取得最高薪水(要求显示 员工名称和薪水)

分析:因为不能使用分组函数,要想取得最高薪水,需要对薪水进行降序排列,然后使用limit来取得记录。

方案一:

SELECT

        ename,sal

FROM

        emp

ORDER BY

        sal desc

LIMIT

        1;

       MySQL34道练习题_第7张图片  

方案二:通过自连接查询出所有小于最高工资的工资。然后查询不在这些工资之内的工资就是最高工资

第一步:查询出所有小于最高工资的工资

SELECT

        distinct e.sal

FROM

        emp e

JOIN

        emp ee

ON

        e.sal < ee.sal;     #查询出所有小于ee表的工资,只有e表中的工资5000不小于ee表中的任何一个工资,所以5000不包括在内。

         MySQL34道练习题_第8张图片       

第二步:查询出最高工资

SELECT

        ename,sal

FROM

        emp

WHERE

        sal not in (SELECT distinct e.sal FROM emp e JOIN emp ee ON e.sal < ee.sal);

          MySQL34道练习题_第9张图片      

说明:方案二虽然复杂了一些,但却是一种不一样的思路,需要我们好好理解一下,也许今后会用到哦!

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

第一种方案:按部门编号分组,计算平均薪水,然后按降序排列,取第一行数据。

SELECT

        deptno,avg(sal) as avgsal

FROM

        emp

GROUP BY

        deptno

ORDER BY

        avgsal desc

LIMIT

        1;

        MySQL34道练习题_第10张图片        

第二种方案:统计出每个部门的平均薪水,然后再查询最大值。

第一步:统计每个部门的平均薪水

SELECT

        deptno,avg(sal)

FROM

        emp

GROUP BY

        deptno;

        MySQL34道练习题_第11张图片       

第二步:把上一步的查询结果当做一张临时表t,统计最大值

SELECT

        t.deptno,max(avgsal)

FROM

        (SELECT deptno,avg(sal) as avgsal FROM emp GROUP BY deptno) t;

         MySQL34道练习题_第12张图片    

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

分析:因为薪水和部门名称分别在emp表和dept表中,为此需要进行连接查询

第一种方案:

SELECT

        d.dname,max(avgsal)

FROM

        (SELECT deptno,avg(sal) as avgsal FROM emp GROUP BY deptno) t     #FROM中的子查询获取的是每个部门的平均薪资

JOIN

        dept d

ON

        d.deptno = t.deptno;

        MySQL34道练习题_第13张图片 

第二种方案:通过连接查询获取部门名称,然后通过GROUP BY分组查询取得部门平均薪资,随后利用ORDER BY进行排序(降序desc)最后通过分页显示截取第一名就是最后结果。

SELECT

        d.dname,avg(sal) as avgsal

FROM

        emp e

JOIN

        dept d

ON

        e.deptno = d.deptno

GROUP BY

        d.dname

ORDER BY

        avgsal desc

LIMIT

        1;

        MySQL34道练习题_第14张图片

7、求平均薪水的等级最低的部门的部门名称

分析:首先按部门进行分组,查询部门最低的平均薪水,然后连接查询找到部门名称

SELECT

        deptno,avg(sal) avgsal

FROM

        emp

GROUP BY

        deptno

ORDER BY

        avgsal asc

LIMIT

        1;

        MySQL34道练习题_第15张图片

把上面的查询结果作为临时表t,与表salgrade进行连接查询,查询工资等级,条件:t.avgsal between s.losal and s.hisal

还需要与表dept d进行连接查询,查询部门名称,条件:t.deptno = d.deptno

SELECT

        d.deptno,d.dname,t.avgsal,s.grade

FROM

        (SELECT deptno,avg(sal) avgsal FROM emp GROUP BY deptno ORDER BY avgsal asc LIMIT 1) t

JOIN

        salgrade s          #通过与表salgrade进行连接查询获取薪资等级

ON

        t.avgsal between s.losal and s.hisal

JOIN

        dept d                #通过与表dept进行连接查询获取部门名称

ON

        t.deptno = d.deptno;

        MySQL34道练习题_第16张图片

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

分析:首先在mgr字段中利用distinct去重查询出所有领导的员工编号。(只要员工编号不在领导编号里的都是普通员工)

第一步:查询领导编号

SELECT

        distinct mgr

FROM

        emp

WHERE

        mgr is not null;

        MySQL34道练习题_第17张图片 

第二步:员工编号不在领导编号里的就是普通员工,查询这些人的最高工资

SELECT

        max(sal)

FROM

        emp

WHERE

        empno not in (SELECT distinct mgr from emp where mgr is not null);

        MySQL34道练习题_第18张图片

第三步:查询sal比上面查询结果(最高工资)高的员工信息(比“普通员工的最高薪水”已经把普通员工排除在外了,所以一定是领导!为此这里不需要判断是不是领导了)

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));

        MySQL34道练习题_第19张图片        

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

分析:按sal字段降序排序,取前五名即可

SELECT

        empno,ename,sal

FROM

        emp

ORDER BY

        sal desc

LIMIT

        5;

        MySQL34道练习题_第20张图片

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

分析:按sal字段降序排序,取第6到第10名即可

SELECT

        empno,ename,sal

FROM

        emp

ORDER BY

        sal desc

LIMIT

        5,5;

         MySQL34道练习题_第21张图片

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

分析:按入职日期按降序排序,取前五名即可

SELECT

        empno,ename,hiredate

FROM

        emp

ORDER BY

        hiredate desc   #这里对日期的比较是1981-01-20大于1981-01-19,所以降序排列的时候晚入职的会排在早入职的前面

LIMIT

        5;

         MySQL34道练习题_第22张图片

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

分析:首先查询出每个员工的薪水等级,然后根据薪水等级进行分组统计数量即可

SELECT

        s.grade as grade,count(*)

FROM

        emp e

JOIN

        salgrade s

ON

        e.sal between s.losal and s.hisal

GROUP BY

        grade;

        MySQL34道练习题_第23张图片 

13、详见上一篇"SQL面试题"

14、列出所有员工及领导的姓名

分析:因为员工和领导都在一张表中,所以需要使用自连接,又因为需要查询所有员工所以需要使用外连接员工表作为主表(员工表中有一位员工没有领导,不使用外连接显示不出来)

第一种方案:左连接

SELECT

        e.ename as '员工名',ee.ename as '领导名'

FROM

        emp e

LEFT JOIN

        emp ee

ON

        e.mgr = ee.empno;    #此处需要注意:员工表的领导编号=领导表的员工编号

        MySQL34道练习题_第24张图片

第二种方案:右连接

SELECT

        e.ename '员工名',ee.ename '领导名'

FROM

        emp ee

RIGHT JOIN

        emp e

ON

        e.mgr = ee.empno;

         MySQL34道练习题_第25张图片

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

分析:首先找出每个员工的直接上级领导,这张表作为临时表,让它与emp表进行连接,条件:

SELECT

        e.empno '员工编号',e.ename as '员工名',e.hiredate as '员工受雇日期',ee.ename as '领导名',ee.hiredate as '领导受雇日期',d.dname '部门名称'

FROM

        emp e

LEFT JOIN    #通过左外链接能查询出所有员工的直接上级领导

        emp ee

ON

        e.mgr = ee.empno  

JOIN            #通过连接查询查询出部门名称

        dept d

ON

        e.deptno = d.deptno

WHERE     

        e.hiredate < ee.hiredate;    #通过条件筛选出员工入职日期早于领导入职日期的信息

MySQL34道练习题_第26张图片

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

分析:员工信息和部门名称在两张表上,并且有一个部门没有员工,要想显示出所有部门就需要让部门表做主表使用外连接

SELECT

        e.*,d.dname

FROM

        dept d

LEFT JOIN

        emp e

ON

        d.deptno = e.deptno;

         MySQL34道练习题_第27张图片

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

分析:需要按部门进行分组查询,然后选出count(*) >= 5 的部门

SELECT

        deptno,count(*)

FROM

        emp

GROUP BY

        deptno

HAVING

        count(*) >= 5;

        MySQL34道练习题_第28张图片 

18、列出薪金比"SMITH" 多的所有员工信息

分析:首先查出'SMITH'的薪资,然后查询比'SMITH'薪资高的员工

SELECT

        ename,sal

FROM

        emp

WHERE

        sal > (SELECT sal FROM emp WHERE ename = 'SMITH');

         MySQL34道练习题_第29张图片

19、列出所有"CLERK"( 办事员) 的姓名及其部门名称, 部门的人数

分析:查询信息不在一张表中,需要使用连接查询;查询部门人数需要按部门进行分组

第一步:通过连接查询,查出工作岗位是'CLERK'的员工姓名、部门名称、部门编号和工作岗位

SELECT

        e.deptno,e.ename,e.job,d.dname

FROM

        emp e

JOIN

        dept d

ON

        e.deptno = d.deptno

WHERE

        job = 'clerk';

MySQL34道练习题_第30张图片

第二步:通过分组查询统计出每个部门的人数

SELECT

        deptno,count(*)

FROM

        emp

GROUP BY

        deptno;

        MySQL34道练习题_第31张图片 

第三步:将前面两步的查询结果作为临时表,查询出最后结果

SELECT

        a.ename,a.job,a.dname,b.count

FROM

        (SELECT e.deptno,e.ename,e.job,d.dname FROM emp e JOIN dept d ON e.deptno = d.deptno WHERE job = 'CLERK') a

JOIN

        (SELECT deptno,count(*) as count FROM emp GROUP BY deptno) b

ON

        a.deptno = b.deptno;

        MySQL34道练习题_第32张图片

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

分析:题中查询各种工作,因此需要根据job来分组查询,分组后还需要筛选出min(sal) > 1500 的组别,然后统计每组人数。

SELECT

        Job,count(*)

FROM

        emp

GROUP BY

        job

HAVING

        Min(sal) > 1500;

         MySQL34道练习题_第33张图片

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

第一步:查询销售部的部门编号

SELECT

        deptno

FROM

        dept

WHERE

        dname = 'SALES';

        MySQL34道练习题_第34张图片 

第二步:将上表查询结果作为条件查询员工姓名

SELECT

        ENAME

FROM

        EMP

WHERE

        DEPTNO = (SELECT DEPTNO FROM DEPT WHERE DNAME = 'SALES');

         MySQL34道练习题_第35张图片

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

第一步:查询公司平均薪资

SELECT

        avg(sal)

FROM

        emp;

第二步:分析查询所在部门需要与dept表连接查询,查询上级领导并显示所有员工需要外自连接查询,查询工资等级需要与salgrade表连接查询。

SELECT

        e.ename, d.dname,ee.ename as '上级领导',s.grade

FROM

        emp e

JOIN

        dept d

ON

        e.deptno = d.deptno

LEFT JOIN

        emp ee

ON

        e.mgr = ee.empno

JOIN

        salgrade s

ON

        e.sal between losal and hisal

WHERE

        e.sal > (SELECT avg(sal) FROM emp);

         MySQL34道练习题_第36张图片

23、 列出与"SCOTT" 从事相同工作的所有员工及部门名称(查询结果不包括'SCOTT')

第一步:查询出'SCOTT'从事的工作

SELECT

        job

FROM

        emp

WHERE

        ename = 'SCOTT';

第二步:需要查询部门名称就要通过与dept表进行连接查询,并将第一步的查询结果作为条件进行查询

SELECT

        e.ename,d.dname,e.job

FROM

        emp e

JOIN

        dept d

ON

        e.deptno = d.deptno

WHERE

        job = (SELECT job FROM emp WHERE ename = 'SCOTT') and ename != 'SCOTT' ;

         MySQL34道练习题_第37张图片

24、列出薪金等于部门30中任意一位员工的薪金的其他部门员工的姓名和薪金。

第一步:查询出部门30的所有员工的薪资

SELECT

        sal

FROM

        emp

WHERE

        deptno = 30;

        MySQL34道练习题_第38张图片 

第二步:查询其他部门的员工薪资等于上表中任意一个薪资的一个姓名和薪资

SELECT

        ename,sal

FROM

        emp

WHERE

        sal in(SELECT sal FROM emp WHERE deptno = 30) and deptno <> 30;

         MySQL34道练习题_第39张图片

25、列出薪金高于在部门 30 工作的所有员工的薪金的员工姓名和薪金. 部门名称

第一步:查询出部门30的最高工资

SELECT

        max(sal)

FROM

        emp

WHERE

        deptno = 30;

        MySQL34道练习题_第40张图片 

第二步:查询工资高于上面查询结果的员工姓名、薪资和部门名称,因为部门名称在另一张表中,所以需要连接查询

SELECT

        e.ename,e.sal,d.dname

FROM

        emp e

JOIN

        dept d

ON

        e.deptno = d.deptno

WHERE

        e. sal > (SELECT max(sal) FROM emp WHERE deptno = 30);

         MySQL34道练习题_第41张图片

26、列出在每个部门工作的员工数量, 平均工资和平均服务期限。

在这里我们首先介绍一个计算两个日期差的函数TimeStampDiff()

语法:

        TimeStampDiff(间隔类型,前一个日期,后一个日期)

        举例:计算两个日期的年差

                timestampdiff(YEAR, hiredate, now())

                此函数的参数'间隔类型'可以是下面内容:

                        SECOND   秒,

                        MINUTE   分钟,

                        HOUR   小时,

                        DAY   天,

                        WEEK   星期

                        MONTH   月,

                        QUARTER   季度,

                        YEAR   年

分析:题中出现每个部门所以需要按部门分组;计算员工数量使用count(ename),计算平均工资使用avg(sal),计算平均服务时长使用avg(timestampdiff()),还有需要注意的地方:本题40部门没有员工,统计员工数量不使用count(*),计算平均工资和平均服务时长时需要处理null,所以需要使用ifnull()函数。

SELECT

        d.deptno,count(e.ename),avg(ifnull(sal,0)),ifnull(avg(timeStampDiff(year,hiredate,now())),0)

FROM

        emp e

RIGHT JOIN

        dept d           #这里使用右连接的目的就是为了显示出所有的部门(包括没有员工的40部门)

ON

        e.deptno = d.deptno

GROUP BY

        d.deptno;     #这里的分组字段也可以把d.dname和d.loc都写上,这样在SELECT后面就可以多写这两个字段,最终显示更详细

         MySQL34道练习题_第42张图片

27、 列出所有员工的姓名、部门名称和工资。

SELECT

        e.ename,d.dname,e.sal

FROM

        emp e

JOIN

        dept d

ON

        e.deptno = d.deptno;

        MySQL34道练习题_第43张图片 

28、列出所有部门的详细信息和人数

SELECT

        d.*,count(e.ename)

FROM

        emp e

RIGHT JOIN

        dept d

ON

        e.deptno = d.deptno

GROUP BY

        e.deptno;

         MySQL34道练习题_第44张图片

29、列出各种工作的最低工资及从事此工作的雇员姓名

第一步:按工作进行分组找出最低工资

SELECT

        job,min(sal) as minsal

FROM

        emp

GROUP BY

        job;

         MySQL34道练习题_第45张图片

第二步:将上表作为临时表t,与表emp e通过连接查询得到结果,连接条件:e.job = t.job and t.minsal = e.sal

SELECT

        e.ename,e.job,e.sal

FROM

        emp e

JOIN

        (SELECT job,min(sal) as minsal FROM emp GROUP BY job) t

ON

        e.job = t.job and t.minsal = e.sal;

         MySQL34道练习题_第46张图片

30、列出各个部门的 MANAGER( 领导) 的最低薪金

分析:按条件job = 'MANAGER'选出所有的'MANAGER',然后对'MANAGER'按deptno进行分组找到最低薪资

SELECT

        DEPTNO,JOB,MIN(SAL)   #这里为什么可以写JOB,是因为查询出的所有人的工作岗位都是一样的,为此可以写JOB。

FROM

        EMP

WHERE

        JOB = 'MANAGER'

GROUP BY

        DEPTNO;

         MySQL34道练习题_第47张图片

31、列出所有员工的年工资, 按年薪从低到高排序

SELECT

        ename,((sal + ifnull(comm,0) ) * 12) as '年薪'

FROM

        emp

ORDER BY

        年薪 asc;                      #注意ORDER BY 后面跟的是字段名,不能写成'年薪'

        MySQL34道练习题_第48张图片 

32、求出员工领导的薪水超过3000的员工名称与领导

SELECT

        e.ename '员工名',ee.ename '领导名',ee.sal as '领导薪资'

FROM

        emp e

JOIN

        emp ee

ON

        e.mgr = ee.empno

WHERE

        ee.sal > 3000;

         MySQL34道练习题_第49张图片        

33、求出部门名称中, 带'S'字符的部门员工的工资合计、部门人数

第一步:查询出部门名称中带'S'的部门

SELECT

        deptno,dname

FROM

        dept

WHERE

        dname like '%S%';

        MySQL34道练习题_第50张图片 

第二步:在上面查询出的部门中统计工资合计、部门人数

SELECT

        t.dname,ifnull(sum(e.sal),0),count(e.ename)

FROM

        emp e

RIGHT JOIN

        (SELECT deptno,dname FROM dept WHERE dname like '%S%') t

ON

        e.deptno = t.deptno

GROUP BY

        t.deptno,t.dname;

        MySQL34道练习题_第51张图片 

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

分析:本题需要计算任职期限需要使用timestampdiff()函数

我们首先查看一下调整前每个人的工资情况和服务期限

SELECT ename,sal,timestampdiff(year,hiredate,now()) from emp;

为了看出满足条件的加薪,不满足条件的没加薪,所以将本题改为:任职期限超过40年的员工

对满足条件的员工工资进行调整

Update emp set sal = sal *1.1 where timestampdiff(year,hiredate,now()) > 40;

查看调整后每个人的工资情况和服务期限

Select ename,sal,timestampdiff(year,hiredate,now()) from emp;

MySQL34道练习题_第52张图片

你可能感兴趣的:(练习题,MySQL,sql,mysql,数据库)