test818

show databases;
create database test818;
use test818;
-- 建表
-- 学生表 
create table Student(
   s_id varchar(20),
   s_name varchar(20) not null default '',
   s_birth varchar(20) not null default '',
   s_sex varchar(20) not null default '',
   primary key (s_id));
-- 课程表
create table Course(
   c_id varchar(20),
   c_name varchar(20) not null default '',
   t_id varchar(20) not null,
   primary key (c_id));
-- 教师表 
create table Teacher(
   t_id varchar(20),
   t_name varchar(20) not null default '',
   primary key(t_id));
-- 成绩表
create table Score(
   s_id varchar(20),
   c_id varchar(20),
   s_score int(3),
   primary key(s_id,c_id));
-- 插入数据
-- 插入学生表测试数据
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-05-20' , '男');
insert into Student values('04' , '李云' , '1990-08-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-03-01' , '女');
insert into Student values('07' , '郑竹' , '1989-07-01' , '女');
insert into Student values('08' , '王菊' , '1990-01-20' , '女');
-- 课程表测试数据
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03');

-- 教师表测试数据
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');

-- 成绩表测试数据
insert into Score values('01' , '01' , 80);
insert into Score values('01' , '02' , 90);
insert into Score values('01' , '03' , 99);
insert into Score values('02' , '01' , 70);
insert into Score values('02' , '02' , 60);
insert into Score values('02' , '03' , 80);
insert into Score values('03' , '01' , 80);
insert into Score values('03' , '02' , 80);
insert into Score values('03' , '03' , 80);
insert into Score values('04' , '01' , 50);
insert into Score values('04' , '02' , 30);
insert into Score values('04' , '03' , 20);
insert into Score values('05' , '01' , 76);
insert into Score values('05' , '02' , 87);
insert into Score values('06' , '01' , 31);
insert into Score values('06' , '03' , 34);
insert into Score values('07' , '02' , 89);
insert into Score values('07' , '03' , 98);


-- 练习
#1.查询'01'课程比02成绩高的学生的信息及学生分数  
#error
select distinct onp.* from 
(select  a.* , b.s_score from Student a ,Score b
where b.c_id = '01' ) as onp,
(select  a.*,b.s_score from Student a,Score b
where b.c_id = '02') as twp
where onp.s_score > twp.s_score;

#正确的做法 
select a.*, b.s_score as 01_score, c.s_score as 02_score from
Student as a
join Score as b on a.s_id = b.s_id and b.c_id = '01'
left join Score as c on a.s_id = c.s_id and c.c_id = '02' or c.c_id = null
where b.s_score > c.s_score;


#3.查询平时成绩大于等于60分的学生编号和学生姓名和平均成绩 
#做对啦 不完美
select a.s_id,a.s_name,avg(s_score)
from student as a
join Score as b on a.s_id = b.s_id
group by s_id
having avg(s_score) > 60;

#答案 
select b.s_id,b.s_name,round(avg(a.s_score)) as avg_score from
Student as b
join Score as a on b.s_id=a.s_id #先连接再group by
group by b.s_id,b.s_name having round(avg(a.s_score),2)>=60;

#5.查询所有同学的学生编号,姓名,选课总数,所有课程总成绩
#自己的做法 错误一:少了Null 应该用left join
#           错误二:不能用count(*) 要用count(b.c_id)
select a.s_id,a.s_name,count(*),sum(b.s_score) 
from Student as a
join score as b on a.s_id = b.s_id
group by a.s_id;
#正确做法 
select a.s_id,a.s_name,count(b.c_id) as sum_course,sum(b.s_score) as sum_score from 
student a 
left join score b on a.s_id=b.s_id
GROUP BY a.s_id,a.s_name;

#6.查询“李”姓老师的数量 
select count(*) from teacher 
where  t_name like '李%';

#7.查询学过张三老师授课的学生的信息  
#自己做对啦 但是和答案思路不一样 
select d.* from score c 
join student as d on c.s_id = d.s_id
where  c.c_id =(
select a.c_id from course as a
join teacher b on a.t_id = b.t_id
where b.t_name = '张三');
#答案--层层递进 
select a.* from 
student a 
join score b on a.s_id=b.s_id where b.c_id in(
select c_id from course where t_id =(
select t_id from teacher where t_name = '张三'));

#8.查询没有学过张三老师授课的学生的信息 
select p.* from student p where p.s_id not in
(select a.s_id from student a 
join score b on a.s_id = b.s_id where b.c_id   in (
select c_id from course where t_id = (
select t_id from teacher where t_name ='张三'))) ;

#9.查询学过01也学过02的课程的同学的信息 
#自己做的 有些复杂了 答案更清晰!!
select m.* from 
(select a.* from student a
where a.s_id in (select s_id from score where c_id = '01')) m
join
(select a.* from student a
where a.s_id in (select s_id from score where c_id = '02')) p
where m.s_id = p.s_id;
#答案 
select a.* from 
Student as a,Score as b,Score as c
where a.s_id=b.s_id and a.s_id=c.s_id and b.c_id='01' and c.c_id='02';

#10查询学过01但没有学过02的同学的信息 
select distinct * from student 
where s_id in (
select s_id from score where s_id not in (
select s_id from score where c_id = '02')
and s_id in(
select s_id from score where c_id = '01'));

#答案 思路更清晰 
select a.* from
Student as a
where a.s_id in (select s_id from score where c_id='01') 
and a.s_id not in (select s_id from score where c_id='02');

#11.查询没有学全所有课程的同学的信息 

select a.*,count(b.s_id) from student a
left join score b on a.s_id = b.s_id
group by b.s_id
having count(b.s_id) < 3;

#12.查询至少有一门课与学号为01的同学所学相同的同学的信息 
#做对啦 和答案思路不同 
select distinct a.* from student a
join score b on a.s_id = b.s_id
where b.c_id in (
select c_id from score where s_id = '01');
#答案
select * from student where s_id in(
    select distinct a.s_id from score a 
    where a.c_id in(select a.c_id from score a where a.s_id='01')
    );

#13.查询和01的同学学习的课程完全相同的其他同学的信息 ???
#没做对 
select  a.* from student a
join score b on a.s_id = b.s_id
where b.c_id = all (
select c_id from score where s_id = '01');

#答案 感觉答案不好 
select  a.* from student a
join score b on a.s_id = b.s_id
where b.c_id in (
select c_id from score where s_id = '01')
group by a.s_id having count(1) = 3;

#14.查询没学过“张三”老师教的任一门课程的学生姓名 
select * from student where s_id not in(
select s_id from score where c_id  in (
select c_id from course
where t_id = (select t_id from teacher where t_name = '张三')));

#15.查询两门以上不及格课程的同学的学号姓名和平均成绩 
select a.s_id,a.s_name ,avg(b.s_score) from student a 
join score b on a.s_id=b.s_id
where a.s_id in
(select s_id from score
where s_score < 60 
group by s_id
having count(1) >=2)
group by b.s_id;

#16.检索01分数小于60,按分数降序排列的学生信息 
#自己做的也对 太繁琐了 
select a.* from student a 
join score b on a.s_id = b.s_id
where a.s_id in(
select s_id from score 
where c_id = '01' and s_score < 60)
and b.c_id = '01'
order by b.s_score desc;
#答案比较简单
select a.*,b.c_id,b.s_score from
student a,score b
where a.s_id=b.s_id and b.c_id='01' and b.s_score <60 order by b.s_score DESC;

#17.按平均成绩从高到底显示所有学生所有课程的成绩以及平均成绩 
#没有思路 
select a.s_id,(select s_score from score where s_id = a.s_id and c_id = '01') as '语文',
(select s_score from score where s_id = a.s_id and c_id = '02') as '数学',
(select s_score from score where s_id = a.s_id and c_id = '03') as '英语',
round(avg(s_score),2) as '平均分' from score a group by a.s_id
order by avg(s_score) desc;

#18.查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
-- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90

###########不会 没啥思路 
select a.c_id,b.c_name ,max(s_score),min(s_score),round(avg(s_score),2),
round(100*(sum(case when a.s_score>=60 then 1 else 0 end)/sum(case when a.s_score then 1 else 0 end)),2) as 及格率,
round(100*(sum(case when a.s_score >= 90 then 1 else 0 end)/sum(case when a.s_score then 1 else 0 end)),2) as 优秀率
from score as a
left join course as b on a.c_id=b.c_id
group by a.c_id,b.c_name;


#19/20
#21.查询不同老师所教不同课程平均分从高到低显示 
select a.c_id,c.t_name, a.c_name,avg(b.s_score) from score b
left join course a on a.c_id = b.c_id
left join teacher c on a.t_id = c.t_id
group by b.c_id
order by avg(b.s_score) desc;


#22.
#23.统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比

#不会 一步步剖析答案 
-- 第一步 按照c_id分类,之前是每个c_id去聚合sum
select c_id,SUM(case when s_score >85 and s_score <=100 then 1 else 0 end) as `85-100`,
ROUND(100*(SUM(case when s_score >85 and s_score <=100 then 1 else 0 end)/count(*)),2) as 百分比
from score GROUP BY c_id;
-- left join的用法~~~~~
select distinct f.c_name,a.c_id,b.`85-100`,b.百分比,c.`70-85`,c.百分比,d.`60-70`,d.百分比,e.`0-60`,e.百分比 from score a
left join (select c_id,SUM(case when s_score >85 and s_score <=100 then 1 else 0 end) as `85-100`,
           ROUND(100*(SUM(case when s_score >85 and s_score <=100 then 1 else 0 end)/count(*)),2) as 百分比
from score GROUP BY c_id)as b on a.c_id=b.c_id
left join (select c_id,SUM(case when s_score >70 and s_score <=85 then 1 else 0 end) as `70-85`,
           ROUND(100*(SUM(case when s_score >70 and s_score <=85 then 1 else 0 end)/count(*)),2) as 百分比
from score GROUP BY c_id)as c on a.c_id=c.c_id
left join (select c_id,SUM(case when s_score >60 and s_score <=70 then 1 else 0 end) as `60-70`,
           ROUND(100*(SUM(case when s_score >60 and s_score <=70 then 1 else 0 end)/count(*)),2) as 百分比
from score GROUP BY c_id)as d on a.c_id=d.c_id
left join (select c_id,SUM(case when s_score >=0 and s_score <=60 then 1 else 0 end) as `0-60`,
          ROUND(100*(SUM(case when s_score >=0 and s_score <=60 then 1 else 0 end)/count(*)),2) as 百分比
from score GROUP BY c_id)as e on a.c_id=e.c_id
left join course f on a.c_id = f.c_id;

#24.
#25.查询各科成绩前3名的记录 
###不会 看答案
-- 第一步 
select a.s_id,a.c_id,a.s_score from score a 
left join score b on a.c_id = b.c_id 
group by a.s_id,a.c_id,a.s_score ;

-- 第二步 加上and 把各科第一名跳出来放在了最后 
select a.s_id,a.c_id,a.s_score from score a 
left join score b on a.c_id = b.c_id and a.s_score < b.s_score
group by a.s_id,a.c_id,a.s_score ;

-- 第三步 为什么是<不是<=
select a.s_id,a.c_id,a.s_score from score a 
left join score b on a.c_id = b.c_id and a.s_score < b.s_score
group by a.s_id,a.c_id,a.s_score having count(b.s_id) <3
order by a.c_id,a.s_score desc;

#26.查询每门课程被选修的学生数 
select c_id,count(s_id) from score 
group by c_id;

#27.查询出只有两门课程的全部学生的学号和姓名 
select a.s_id,a.s_name from student a
where a.s_id in(
select s_id from score 
group by s_id having count(c_id) =2);

#28.查询男生,女生人数 
select s_sex,count(*) from student group by s_sex;

#29.31
#30.查询同名同姓的学生名单,并且统计同名人数 
#自己做的 答非所问 
select count(*),s_name from student group by s_name;
#正确答案 
select a.s_name,a.s_sex ,count(*) from student a join
student b on a.s_id !=b.s_id and a.s_name = b.s_name
group by a.s_name,a.s_sex;

#32.查询每门课程的平均成绩,结果按平均成绩降序排雷,平均成绩相同时,按照课程编号排序
select c_id,avg(s_score) from score 
group by c_id
order by avg(s_score) desc, c_id;

#33.查询平均成绩大于等于85的所有学生的学号 姓名 平均成绩 
select a.s_id, a.s_name, avg(b.s_score) from student a
left join score b on a.s_id = b.s_id
group by b.s_id
having avg(b.s_score)>=85;

#34.查询课程名称为‘数学’,而且分数低于60的学生姓名和分数 
select a.s_id,b.c_id,a.s_name,b.s_score from student a
left join score b on a.s_id = b.s_id
where b.c_id =(
select c_id from course where c_name = '数学')
and b.s_score <60;

#35.查询所有学生的课程及分数情况 
#自己做的没有行列转换 
select a.s_id,a.s_name ,b.c_id,c.c_name,b.s_score from score b
left join student a on a.s_id = b.s_id
left join course c on c.c_id = b.c_id
order by s_id, s_name;

#正确答案 更好的形式 
select a.s_id,a.s_name,
SUM(case c.c_name when '语文' then b.s_score else 0 end) as '语文',
SUM(case c.c_name when '数学' then b.s_score else 0 end) as '数学',
SUM(case c.c_name when '英语' then b.s_score else 0 end) as '英语',
SUM(b.s_score) as  '总分'
from student a left join score b on a.s_id = b.s_id 
left join course c on b.c_id = c.c_id 
GROUP BY a.s_id,a.s_name;

#36.查询任何一门课程成绩在70分以上的姓名 
select s_id ,s_name from student
where s_id in (
select s_id from score group by s_id having count(s_score > 70)>1);

#答案做法 
select a.s_name,b.c_name,c.s_score from course b 
left join score c on b.c_id = c.c_id
left join student a on a.s_id=c.s_id where c.s_score>=70;
#37.
#38.查询课程编号为01且课程成绩在80 分以上的学生学号和姓名 
select a.s_id,a.s_name from student a
join score b on a.s_id = b.s_id and b.c_id = '01'
where  b.s_score >=80;

#39
#40查询选择张三老师所教课程的学生中 ,成绩最高的学生信息 
#自己的做法 --先排序再limit
select a.* from student a 
where a.s_id = (select b.s_id from score b
                join course c on c.c_id = b.c_id 
                where c.t_id =(select t_id from teacher where t_name = '张三')
                order by b.s_score desc
                limit 1);

#答案做法 
select a.*,b.s_score,b.c_id,c.c_name from student a
LEFT JOIN score b on a.s_id = b.s_id
LEFT JOIN course c on b.c_id=c.c_id
where b.c_id =(select c_id from course c,teacher d where c.t_id=d.t_id and d.t_name='张三')
and b.s_score in (select MAX(s_score) from score where c_id='02');

#41.查询不同课程成绩相同的学生的学生编号,课程编号,学生成绩 
####竟然不会 
select distinct a.s_id,a.c_id,a.s_score from score a
join score b on a.s_score = b.s_score and a.c_id!=b.c_id;

#42.查询每门成绩最好的前两名 
##不会 -- 注意where条件是c_id相同 然后一个的分数再大于另一个 
select a.s_id,a.c_id,a.s_score from score as a
where (select count(1) from score b where b.c_id = a.c_id and b.s_score >=a.s_score)<=2
order by a.c_id;

#43.
#44.查询至少选修两门课程的学生学号 
select s_id from score a
group by s_id
having count(c_id)>=2;

#45.查询各学生的年龄 

猜你喜欢

转载自blog.csdn.net/kylin_learn/article/details/81836244