python学习笔记 day44 mysql练习题(四)

习题来自于: http://www.cnblogs.com/wangfengming/articles/7891939.html

习题答案来自于: https://www.cnblogs.com/wangfengming/articles/7978354.html

需要创建的表结构如下:

首先创建学生表 student:

-- 创建学生表
create table student(
  s_id smallint unsigned not null auto_increment primary key,  -- 学生编号
  s_name varchar(40) not null,  -- 姓名
  s_age int not null, -- 年龄
  s_sex char(2) not null) -- 性别
insert into student(s_name,s_age,s_sex) values("鲁班",12,"男");
insert into student(s_name,s_age,s_sex) values("貂蝉",20,"女");
insert into student(s_name,s_age,s_sex) values("刘备",35,"男");
insert into student(s_name,s_age,s_sex) values("关羽",34,"男");
insert into student(s_name,s_age,s_sex) values("张飞",33,"女");

select * from student;

-- 创建老师表
create table teacher(
  t_id smallint unsigned not null auto_increment primary key,-- 教师编号
  t_name varchar(40) not null)  -- 教师姓名

insert into teacher(t_name) values("大王"),("alex"),("egon"),("peiqi")

-- 创建课程表

create table course(
  c_id smallint unsigned not null auto_increment primary key,  -- 课程编号
  c_name varchar(40) not null,  -- 课程名字
  t_id smallint unsigned not null) -- 教师编号

insert into course(c_name,t_id) values("python",1),("java",2),("linux",3),("go",2)

-- 创建成绩表
create table score(
  id smallint unsigned not null auto_increment primary key,  -- 成绩编号
  s_id smallint unsigned not null,  -- 学生编号
  c_id smallint unsigned not null, -- 课程编号
  result int not null)  -- 成绩得分

insert into score(s_id,c_id,result) values(1,1,79);
insert into score(s_id,c_id,result) values(1,2,77);
insert into score(s_id,c_id,result) values(1,3,58);
insert into score(s_id,c_id,result) values(2,2,66);
insert into score(s_id,c_id,result) values(2,3,77);
insert into score(s_id,c_id,result) values(3,1,61);
insert into score(s_id,c_id,result) values(3,2,64);
insert into score(s_id,c_id,result) values(4,3,70);

1. 查询学习课程"python"比课程 "java" 成绩高的学生的学号;

select t1.s_id,t1.id,t1.result as python_result,t2.result as java_result from score as t1 left JOIN     -- 把socre表与只取了c_id=2的socre表进行左连接,连接条件是两者的s_id相等,
(select s_id,result from score where c_id=2)as t2                       -- 筛选条件是t1的c_id=1(选python成绩) 并且t1.result>t2.result(表示python成绩比java成绩高)
on t1.s_id=t2.s_id
where t1.c_id=1 and t1.result>t2.result;

运行结果:


2. 查询平均成绩大于65分的同学的姓名和平均成绩(保留两位小数);  

select s_name,format(result_avg,2)as result_avg from student inner join   -- result_avg是平均成绩 format(resulr_avg,2)对平均成绩保留两位小数
(select s_id,avg(result)as result_avg from score group by s_id having result_avg>65 )as t2 -- 对score表按照s_id分组,计算每一组学生的平均成绩(分组条件是result_avg>65) 然后和student表内链接
on student.s_id=t2.s_id  -- 内连接条件是两张表的s_id相等;

 运行结果:

3. 查询所有同学的姓名、选课数、总成绩

select s_name,course_number,result_sum from student left join   -- 将student表与score表(基于s_id分组,求出每位学生的选课数count(c_id) 总成绩sum(result))
(select s_id,count(c_id)as course_number,sum(result)as result_sum from score group by s_id) as t2 -- 两表左连接 连接条件是s_id相等
on student.s_id=t2.s_id;

运行结果:

4. 查询所有的课程的名称以及对应的任课老师姓名;

 采用左连接查询:

select c_name,t_name from course left JOIN 
(select t_id,t_name from teacher)as t2
on course.t_id=t2.t_id;

运行结果:


 5. 查询没学过“alex”老师课的同学的姓名;

方法一 :(思路是好的,但是最后发现group_concat 来判断根本行不通!!)

错误:

select t1.s_ids,t1.c_id from   -- 两张临时表左连接 连接字段是c_id score  ,这样可以基于两张临时表筛选出t1.s_ids c_id就是选过alex课得学生编号
(select GROUP_CONCAT(s_id)as s_ids,c_id from score group by c_id) as t1  -- 首先按照c_id分组得到t1表
inner join (select c_id from course where t_id =(select t_id from teacher where t_name="alex"))as t2 -- course表中基于t_id=2的条件筛选的c_id得到的t2表
on t1.c_id=t2.c_id;
select s_id,s_name from student where s_id not in 
(select t1.s_ids from   -- 两张临时表左连接 连接字段是c_id score  ,这样可以基于两张临时表筛选出t1.s_ids c_id就是选过alex可得学生编号
(select GROUP_CONCAT(s_id)as s_ids,c_id from score group by c_id) as t1  -- 首先按照c_id分组得到t1表
inner join (select c_id from course where t_id =(select t_id from teacher where t_name="alex"))as t2 -- course表中基于t_id=2的条件筛选的c_id得到的t2表
on t1.c_id=t2.c_id)

 运行结果:(错误版本):

 方法二:(啊  我要崩溃了,先跳过,写不出来了23333)

嗯,我吃完饭回来很随意的写出来了,,,,(所以是刚才饿的宝宝大招没使出来???) 

select s_name from student where s_id not in 
(select s_id from score
 left join 
(select c_id as cid from course where t_id=(select t_id from teacher where t_name="alex")) as t2
on score.c_id=t2.cid
where cid is not null);

(其实应该用内连接,这样最后cid字段非空的条件就不用加了)

思路就是:首先把 teacher表中t_name 为alex的t_id选出来,然后根据t_id 去course表中找到该老师相应的课程,将该临时表与score表进行连接,连接条件是c_id相等,然后筛选出来的就是上过该老师课的学生s_id ;

接下来就直接去student表中过滤就行了~

 6 . 查询学过'python'并且也学过编号'java'课程的同学的姓名;

这个题跟上面那个题思路差不多:

select s_id,s_name from student where s_id in (
select s_id from score      -- 将score表与筛选出c_id的临时表进行内链接
inner join 
(select c_id as cid from course where c_name in ("java","python"))as t2  -- 首先把c_name=java python的c_id 从course表筛选出来
on score.c_id=t2.cid
group by s_id having count(c_id)>=2   -- 将连接之后的表按照s_id分组,然后查找count(c_id)>2的那些s_id就是同时选了python和java的同学
);

运行结果:

 7. 查询学过“alex”老师所教的全部课程的同学的姓名;

猜你喜欢

转载自www.cnblogs.com/xuanxuanlove/p/9901799.html