自学内容网 自学内容网

MySql基础34题写题记录(11-20)

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

select ename from emp order by hiredate desc limit 5;

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

    先取每个员工的薪水等级

Select e.ename,s.grade grade

From emp e

Join salgrade s

On e.sal between s.losal and s.hisal

    接着直接分组求

Select a.grade,count(*)

From (Select e.ename,s.grade grade

From emp e

Join salgrade s

On e.sal between s.losal and s.hisal) a

Group by grade;

13、面试题

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

Select distinct s.sname

From sc

Join s

On sc.sno = s.sno

Join c

On sc.cno = c.cno

Where c.cteacher != ‘黎明’;

Select s.sname,c.cname,c.cno

From sc

Join s

On sc.sno = s.sno

Join c

On sc.cno = c.cno

Where c.cteacher != ‘黎明’;

       第一个问题是用的cmd窗口输入,因此编码有问题,无法得知是代码的问题还是编码的问题,因此把老师名字改成课号

       第二个问题是和之前一样的,因为笛卡尔积,把所有的都求出来了,一个人选了很多门课,题目的要求是,只要存在,即删去这个人名,但是程序的只要这一行数据没有,就保留,最后就会把不该保留的保留

       尝试按照名字分组,使用having对分组数据进行再次过滤

Select s.sname,c.cname,c.cno

From sc

Join s

On sc.sno = s.sno

Join c

On sc.cno = c.cno

Where s

    还是失败了,采用先把选5号课的学生找出来,再用not in求

    选5号课的学生(要找老师也是同理)

Select s.sname

From s

Join sc

on s.sno = sc.sno

Where sc.cno = 5;

    接着排除

Select s.sname

From s

Where s.sname not in (Select s.sname

From s

Join sc

on s.sno = sc.sno

Where sc.cno = 5);

(2)先找到学生未及格门数的表

       Select

           s.sname,avg(sc.scgrade)

       From

           S

       Right Join //这里右联,应该是为了完整性,但是看起来好像不用

           Sc

       On

           s.sno = sc.sno

       where

           sc.scgrade < 60

       Group by

           Sno

       Having

           Cout(grade) >= 2;//改成Cout(s.sname) >= 2,因为在成绩表中,一个学号对应多个课号,对应有多个成绩,因此前面where查到的不及格的课程,有几个就有几个名字,所以就统计有多少个名字就知道有多少科没过

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

    找出学过一号课程的学生学号,再找到学过二号课程的学生学号,然后找重合的,最后联合s表,查到学生名字

Select s.sname

From (select sc.sno,sc.cno from sc where sc.cno = 1 ) a

Join (select sc.sno,sc.cno from sc where sc.cno = 2 ) b

On b.sno = a.sno

Join s

On a.sno = s.sno;

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

Select a.ename,b.ename mgr

From emp a

Left Join emp b

On a.mgr = b.empno;

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

    这里的问题是,入职越早,时间就越小,所以入职早的反而小于入职晚的

先得到员工编号,姓名,部门编号,上级编号表,并求得受雇日期较早的员工

Select a.ename,a.empno,a.deptno,b.empno mgr

From emp a

Left Join emp b

On a.mgr = b.empno

Where a.hiredate < b.hiredate;

    内连,得到部门名称

Select d.dname,c.empno,c.ename

From (Select a.ename,a.empno,a.deptno,b.empno mgr

From emp a

Left Join emp b

On a.mgr = b.empno

Where a.hiredate < b.hiredate) c

Join dept d

On d.deptno = c.deptno;

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

Select e.*,d.dname

From emp e

Right Join dept d

On e.deptno = d.deptno;

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

    先找到有5个及以上员工的部门编号

Select deptno,count(*) sum

From emp

Group by deptno

Having count(*) >= 5;

    再多表查询,找到部门名字

Select d.dname,a.sum

From dept d

Join (Select deptno,count(*) sum

From emp

Group by deptno

Having count(*) >= 5) a

On d.deptno = a.deptno;

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

Select *

From emp

Where sal > (select sal from emp where ename = ‘smith’);

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

    这里总是报错,最后发现是要把where语句放到join on 语句后面,要不然执行顺序不对

    找到办事员的姓名,部门名称,再和部门人数表联合,得到部门人数

Select e.ename,d.dname

From emp e

Join dept d

On e.deptno = d.deptno

Join (Select deptno,count(*) sum

From emp

Group by deptno) a

On e.deptno = a.deptno

Where e.job = ‘clerk’

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

    先找个每个工作的最低薪资和雇员人数

Select min(sal) min_sal,job,count(ename)

From emp

Group by job

    再找到大于1500的

Select *

From (Select min(sal) min_sal,job,count(ename)

From emp

Group by job

) a

Where a.min_sal >1500;


原文地址:https://blog.csdn.net/Xjhhhhh/article/details/142833014

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!