wl413911

sql面试题(一)

数据描述:3张表(学生表、课程表、分数表)

 创建表

创建学生表:包含 id 、name两个字段
1
create table student( 2 id int unsigned primary key auto_increment, 3 name char(10) not null 4 ); 5 insert into student(name) values('张三'),('李四'); 6


创建课程表:包含 id 、课程名称两个字段
 7 create table course(
 8 id int unsigned primary key auto_increment,
 9 name char(20) not null
10 );
11 insert into course(name) values('语文'),('数学');
12

创建分数表:包含sid 、cid 、score 三个字段
13
create table student_course( 14 sid int unsigned, 15 cid int unsigned, 16 score int unsigned not null, 17 foreign key (sid) references student(id), 18 foreign key (cid) references course(id), 19 primary key(sid, cid) 20 ); 21 insert into student_course values(1,1,80),(1,2,90),(2,1,90),(2,2,70);


 

第一题:在student_course 表查询各科成绩最高的学生,结果列出学生id, 课程id,最高分数

知识点:在where子句中的嵌套子查询

问题迷惑点:容易想到按照课程id分组,用聚合函数max() 求最高成绩,但是无法返回非分组列 的信息(比如本题的  学生id)

      从本题可以看出,where子句中的 相关子查询 可以起到分组查询的效果

 1 select * 
 2 from student_course as a
 3 where score >= (select max(score) as max_score 
 4                         from student_course as b
 5                         where b.cid = a.cid);
 6 
 7 
 8 -- 也可以用all(),只是比用聚合函数效率低一些
 9 
10 select * 
11 from student_course as a
12 where score >= (select score 
13                          from student_course as b
14                          where b.cid = a.cid);


补充知识点:嵌套子查询

  (1)子查询:嵌套在其他查询之中的查询,被嵌套的查询叫主查询

  (2)子查询可分为两类-- 1、相关子查询  2、 非相关子查询

      * 非相关子查询: 子查询独立于主查询,仅执行一次,将查询结果传递给主查询,查询效率高

      * 相关子查询:依赖于主查询,主查询执行一次,子查询也执行一次

  (3)如果考察返回值的情况,子查询一般分为  --1、返回一个单值的子查询  2、返回一个列表的子查询

   (4) 相关子查询多是出现在 主查询的where子句中,执行过程如下:

      1、从外层查询中取出一个元组,将元组相关列的值传给内层查询(注:表的一行 称为一个  元组)

      2、执行内层查询,得到子查询操作的值

      3、外查询根据子查询得到的结果或结果集得到满足条件的行

      4、然后外层查询取出下一个元组重复做1-3步骤,直到外层元组全部处理完毕。

 

 

第二题:在student_course 表中查询课程 1 成绩第二高的学生,如果第二高的 学生不止一个,列出所有学生

知识点:limit [offset][size]   : 第一个参数是偏移量(第一行 偏移量为 0),第二个参数是返回的最大数量

    limit 后面只有一个数字n时,代表返回前n条数据

1 select *
2 from student_course 
3 where cid = 1 and score = ( select  score 
4              from student_course
5              where cid =1 
6              group by score
7                  order by score desc
8              limit 1,1);
9               

 

 

第三题:在student_course 表中列出平均分不及格(小于60)的学生,列出id 和 平均分

知识点:group by  用having过滤分组,可以使用聚合函数作为过滤条件

1 select sid ,avg(score) as avg_score
2 from student_course 
3 group by sid
4 having avg_score < 60

 

第四题:在student_course表中查询每门课成绩都不低于80的学生id

知识点:方向思考,将问题转化为其等价问题

1 select distinct sid
2 from student_course
3 where sid not in (
4 select sid from student_course
5 where score < 80);

 

第五题:查询每个学生的总成绩,结果列出学生姓名和总成绩

select s.name, sum(sc.score) as sum_score
from student  as s left join student_course as sc
on s.id = sc.sid
group by s.id

 

  

 

 

posted on 2019-09-06 22:38  wl413911  阅读(273)  评论(0编辑  收藏  举报