MySQL—练习2

参考链接:https://www.cnblogs.com/edisonchou/p/3878135.html   感谢博主

     https://blog.csdn.net/flycat296/article/details/63681089

 一、建表,插入数据

create database zuoye2;
use zuoye2;

CREATE TABLE Student 
  ( 
     S    INT, 
     Sname nvarchar(32), 
     Sage  INT, 
     Ssex  nvarchar(8) 
  ) ;

CREATE TABLE Course 
  ( 
     C    INT, 
     Cname nvarchar(32), 
     T    INT 
  ) ;

CREATE TABLE Sc 
  ( 
     S    INT, 
     C    INT, 
     score INT 
  ) ;

CREATE TABLE Teacher 
  ( 
     T    INT, 
     Tname nvarchar(16) 
  );

insert into Student select 1,N'刘一',18,N'' union all
 select 2,N'钱二',19,N'' union all
 select 3,N'张三',17,N'' union all
 select 4,N'李四',18,N'' union all
 select 5,N'王五',17,N'' union all
 select 6,N'赵六',19,N'' ;
 
 insert into Teacher select 1,N'叶平' union all
 select 2,N'贺高' union all
 select 3,N'杨艳' union all
 select 4,N'周磊';
 
 insert into Course select 1,N'语文',1 union all
 select 2,N'数学',2 union all
 select 3,N'英语',3 union all
 select 4,N'物理',4;
 
 insert into SC 
 select 1,1,56 union all 
 select 1,2,78 union all 
 select 1,3,67 union all 
 select 1,4,58 union all 
 select 2,1,79 union all 
 select 2,2,81 union all 
 select 2,3,92 union all 
 select 2,4,68 union all 
 select 3,1,91 union all 
 select 3,2,47 union all 
 select 3,3,88 union all 
 select 3,4,56 union all 
 select 4,2,88 union all 
 select 4,3,90 union all 
 select 4,4,93 union all 
 select 5,1,46 union all 
 select 5,3,78 union all 
 select 5,4,53 union all 
 select 6,1,35 union all 
 select 6,2,68 union all 
 select 6,4,71

 

二、开始练习

四张表分别如下:course,  sc,  student,  teacher

#(1)查询“001”课程比“002”课程成绩高的所有学生的学号;
select * from 
(select * from sc where c=1) as a,
(select * from sc where c=2) as b
where a.s = b.s and a.score > b.score

#其实跟这个一样,就是先把=1=2两个表查询出来拼接,然后再筛选
select * from 
(select * from sc where c=1) as a inner JOIN
(select * from sc where c=2) as b on a.s = b.s
where a.score > b.score

#(2) 查询平均成绩大于60分的同学的学号和平均成绩; 
select s,avg(score) as avgscore from sc group by s having avgscore > 60
#分组之后的条件直接用having就可以啦

#(3)查询所有同学的学号、姓名、选课数、总成绩;
select b.s,b.sname,a.countscore,a.sumsocre from 
(select sum(score) as sumsocre,s,count(1) as countscore from sc group by s) as a
inner join student as b on b.s = a.s
#在两张表中,先查询选课数,总成绩,然后拼接到student中就好啦

#(4)查询姓“李”的老师的个数;
select count(1) from teacher where tname like '李%'
#熟悉like的用法

#(5)查询没学过“叶平”老师课的同学的学号、姓名;
select s,sname from student where s not in 
(select s from sc where c in (select c from course where t in (select t from teacher where tname = '叶平')))
#一层层嵌套,只要知道哪些是学过的,然后not in就可以啦

#(6)查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
select s,sname from student where s in 
(select a.s from 
(select * from sc where c=1) as a,
(select * from sc where c=2) as b
where a.s = b.s);
#学过1也学过2的使用拼接来查询出来,然后再查学号姓名

#(7)查询学过“叶平”老师所教的所有课的同学的学号、姓名;
select s,sname from student where s in
(select s from sc where c in (select c from course where t in (select t from teacher where tname = '叶平')))
#UPDATE teacher set tname = '叶平' where t=2
select s,sname from student where s in (select s from (select s,count(1) as counts from (select sc.*,course.cname,course.t,teacher.tname from sc left join course on course.c = sc.c left join teacher on course.t = teacher.t where tname='叶平') 
as a group by a.s) as b where counts = (select count(1) from course where t in (select t from teacher where tname = '叶平')))
#这个不能按照前面那样来做,比如叶平更改成两个的话,发现就不对了,这里的思路是,学生学习叶平课程的数量=叶平教学的数量

select s,count(1) from sc where c in (select c from course where t in (select t from teacher where tname='叶平')) group by s ;   #这个查询学生选择叶平课程的数量
select count(1) from course where t in (select t from teacher where tname = '叶平');   #叶平一共课程是2
select s from sc where c in 
(select c from course where t in (select t from teacher where tname='叶平')) group by s 
having count(1) = (select count(1) from course where t in (select t from teacher where tname = '叶平'));
#两个拼接起来
select s,sname from student where s in (select s from sc where c in 
(select c from course where t in (select t from teacher where tname='叶平')) group by s 
having count(1) = (select count(1) from course where t in (select t from teacher where tname = '叶平')))

 先查询每个学生叶平课程数量,在查询叶平教学2门,然后查出那些刚好是两门的学生,再查学生的信息

 

#(8)查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
select s,sname from student where s in(select a.s from 
(select * from sc where c=1) as a,
(select * from sc where c=2) as b
where a.s = b.s and a.score > b.score)
#跟前面那题差不多,就是拼接再查

#(9)查询有课程成绩小于60分的同学的学号、姓名;
select s,sname from student where s in (select DISTINCT s from sc where score < 60)
#比较简单

 

#(10)查询没有学全所有课的同学的学号、姓名;
select count(1),s from sc group by s;
select count(DISTINCT c) from sc;
select s,sname from student where s in (select s from sc group by s having count(1) < (select count(DISTINCT c) from sc));
#查询每个同学的课程数
#查询一共课程数
#小于总共课程数的学生查出来

#(11)查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名;
select * from sc where c=1;
select s,sname from student where s in (select s from sc where c in (select c from sc where s=1));
#查出1号同学学过的课程c,然后只要有学这些C的同学都可以

 

#(12)查询至少学过学号为“001”同学所有一门课的其他同学学号和姓名;(感觉跟11题有重叠)

#(13)把“SC”表中“叶平”老师教的课的成绩都更改为此课程的平均成绩;

#(14)查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名;
select * from sc where s=2;
select s,sname from student where s !=2 and s in (select s from sc where c in (select c from sc where s=2) group by s having count(1) = (select count(1) from sc where s=2))
#这个做法是先查询出所有修过2号同学那些课程的条目,然后group by之后如果count数量与2号同学的count数量一致,那么就筛选出来。

 

#(15)删除学习“叶平”老师课的SC表记录;
delete from sc where c in (select c from course where t in (select t from teacher where tname = '叶平'))
#(17)按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分;
select DISTINCT sc.s as '学生ID',a.score as '语文',b.score as '数学',c.score as '英语',d.num as '有效课程数',avgscore as '有效平均分' from sc
left join (select s,score from sc where c = 1) as a on sc.s = a.s
left join (select s,score from sc where c = 2) as b on sc.s = b.s
left join (select s,score from sc where c = 3) as c on sc.s = c.s
left join (select s,count(1) as num from sc group by s) as d on sc.s = d.s
left join (select s,avg(score) as avgscore from sc group by s) as e on sc.s = e.s
order by avgscore
#一个个查询出来后拼接起来,方法感觉比较蠢

#(18)查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分;
select a.c,maxsc as '最高分',minsc as '最低分' from (select c,max(score) as maxsc from sc group by c) as a left join (select c,min(score) as minsc from sc group by c) as b on a.c = b.c;

#(19)按各科平均成绩从低到高和及格率的百分数从高到低顺序;
select a.c,a.avgsc,jige / zong * 100 from 
(select c,avg(score) as avgsc,count(1) as zong from sc GROUP BY c) as a 
left join 
(select c,count(1) as jige from sc where score >=60 group by c) as b
on a.c=b.c;

#(21)查询不同老师所教不同课程平均分从高到低显示;
select sc.c,avg(score) as avgsc,tname,cname from sc left join course as a on a.c = sc.c left join teacher as b on b.t = a.t group by sc.c order by avgsc desc

#(23)统计列印各科成绩,各分数段人数:课程ID,课程名称,[100-85],[85-70],[70-60],[ <60] 
select sc.c,max(cname),
sum(case when sc.score between 85 and 100 then 1 else 0 end) as '[85-100]',
sum(case when sc.score between 70 and 85 then 1 else 0 end) as '[70-85]',
sum(case when sc.score between 60 and 70 then 1 else 0 end) as '[60-70]',
sum(case when sc.score between 0 and 60 then 1 else 0 end) as '[0-60]'
from sc left join course as a on a.c = sc.c
group by c

#(26)查询每门课程被选修的学生数;
select sc.c,cname,count(1) from sc left join course as a on sc.c = a.c group by c;
#(27)查询出只选修了一门课程的全部学生的学号和姓名;
select sc.s,sname from sc LEFT JOIN student as a on a.s=sc.s group by s having count(1) =3;

 

#(28)查询男生、女生的人数;
select count(2),ssex from student group by ssex;
#(29)查询姓“张”的学生名单;
select * from student where sname like '张%';
#(30)查询同名同姓学生名单,并统计同名人数;
select sname from student group by sname having count(1)>1
#(32)查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列;
select c,avg(score) as avgscore from sc group by c order by avgscore,c desc;
#(33)查询平均成绩大于85的所有学生的学号、姓名和平均成绩;
select s,avg(score) as avgscore from sc group by s having avgscore > 85;
#(34)查询课程名称为“数学”,且分数低于60的学生姓名和分数;
select * from sc where c = (select c from course where cname = '数学') and score < 60
#(35)查询所有学生的选课情况;
select sc.s,b.sname,a.cname,sc.c from sc left join course as a on a.c = sc.c left join student as b on b.s = sc.s;

 

 后面的题目感觉简单了太多。重点还是前面的三十题吧。

 

posted @ 2018-04-11 14:57  慢慢来会比较快  阅读(740)  评论(0编辑  收藏  举报