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.查询各学生的年龄
test818
猜你喜欢
转载自blog.csdn.net/kylin_learn/article/details/81836244
今日推荐
周排行