文章目录
- 1.查询"01"课程比 "02" 课程成绩高的学生的信息及课程分数
- 2.查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
- 3.查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
- 4.查询姓“张”的老师个数
- 5.查询没学过张三老师课的学生的学号和姓名
- 6.查询学过张三老师所教的所有课程的同学的学号和姓名
- 7.查询学过01课程并且学过02课程的学生
- 8.查询学过02课程的总成绩
- 9.查询所有课程成绩小于60的学生
- 10.查询没有学全所有课的学生学号、姓名
- 11.查询至少有一门课与学号为“01”的学生所学课程相同的学生学号、姓名
- 12.查询和“01”学号学生所学课程完全相同的学生学号
- 13.查询没学过"张三"老师讲授的任一门课程的学生姓名
- 14.查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩
- 15.查询两门及其以上不及格的同学的学号、姓名和平均成绩
- 16.检索01课程分数小于60 ,按课程分数降序排列学生信息
- 17.按平均成绩从高到低显示所有学生的所有课程的成绩和平均成绩
- 18.查询各科成绩最高分、最低分、平均分、及格率、中等率、优良率、优秀率
- 19.按各科成绩进行排序,并显示排名
- 20.查询学生的总成绩并进行排名
- 21.查询不同老师所教不同课程平均分从高到低展示
- 22 .查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
- 23.使用分段来统计各科成绩,分别统计各分数段人数:课程ID和课程名称
- 24.查询学生平均成绩以及排名
- 25.查询各科成绩前三名的记录(不考虑成绩并列情况)
- 26.查询每门课程被选修的学生数
- 27.查询出只有两门课程的全部学生的学号和姓名
- 28.查询男生、女生人数
- 29. 查询名字中含有"三"字的学生信息
- 30.查询同名同性学生名单,并统计同名同性人数
- 31.查询1990年出生的学生名单
- 32.查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩
- 33.查询每门课程的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列
- 34.查询课程名称为"数学",且分数低于60的学生姓名和分数
- 35.查询所有学生的课程及分数情况
- 36.查询任何一门课程成绩在70分以上的姓名、课程名称和分数
- 37.查询不及格的课程并按课程号从大到小排列
- 38.查询课程编号为03且课程成绩在80分以上的学生的学号和姓名
- 39.求每门课程的学生人数
- 40.查询选修“张三”老师所授课程的学生中成绩最高的学生姓名及其成绩
- 41.查询某个不同课程但成绩相同的学生编号、课程编号、学生成绩
- 42.查询每一门课程最好的前两名
- 43.统计每门课程的学生选修人数(超过5人的课程才统计)。
- 44.检索至少选修两门课程的学生学号
- 45.查询选修了全部课程的学生信息
- 46.查询各学生的年龄
- 47.查询本周过生日的学生
- 48.查询下周过生日的学生
- 49.查询本月过生日的学生
- 50.查询下月过生日的学生
1.查询"01"课程比 “02” 课程成绩高的学生的信息及课程分数
# 方法1思路 在课程和学生中间表中,按照学生分组,得到每个学生的全部课程,然后挑选查询出01课程的和02课程的,
# 然后对分组后的结果过滤出"01"课程比 "02" 课程成绩高的学生,然后与学生表连接得到学生信息以及分数
# 查询"01"课程比 "02" 课程成绩高的学生
select s_id, max(case when c_id ='01' then score else 0 end)score01,max(case when c_id ='02' then score else 0 end) score02
from sc
group by s_id
having score01 >score02;
# 查询"01"课程比 "02" 课程成绩高的学生的信息及课程分数
select s.*,temp.score01,temp.score02
from student as s
inner join (
select s_id, max(case when c_id ='01' then score else 0 end)score01,max(case when c_id ='02' then score else 0 end) score02
from sc
group by s_id
having score01 >score02) as temp
on s.s_id =temp.s_id;
#方法2思路:分两种情况: (1)"01"课程、 "02" 课程成绩都存在。(2) "01"课程存在,但“02”课程成绩不存在(3)合并,然后与学生表连接得到学分数
select sc01.s_id, sc02.s_id ,sc01.c_id,sc02.c_id, sc01.score,sc02.score
from sc as sc01
inner join sc as sc02
on sc01.c_id='01' and sc02.c_id='02'
where (sc01.s_id=sc02.s_id and sc01.score>sc02.score)
union all
select sc01.s_id, sc02.s_id ,sc01.c_id,sc02.c_id, sc01.score,sc02.score
from sc as sc01
left join sc as sc02
on sc01.s_id=sc02.s_id and sc02.c_id='02'
where sc01.c_id='01' and sc01.score is not null and sc02.score is null;
2.查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
# 方法一
select s.s_id,s.s_name,temp.average
from student as s
inner join
(select s_id, round( avg(score),1) average
from sc
group by s_id
having avg(score)>=60 ) as temp
on s.s_id =temp.s_id;
# 方法2
select s.s_id,s.s_name, round( avg(sc.score),1) average
from sc
inner join student as s
on s.s_id =sc.s_id
group by sc.s_id,s.s_name
having avg(sc.score)>=60;
3.查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩
select s.s_id,s.s_name,temp.count,temp.sum
from student as s
left join
(select s_id, count(c_id) as count,sum(score) as sum from sc
group by s_id) as temp
on s.s_id =temp.s_id;
4.查询姓“张”的老师个数
select count(*) as count
from teacher
where t_name like '张%';
5.查询没学过张三老师课的学生的学号和姓名
# 方法1
select s.s_id,s_name from student as s where s_id in(select s_id from sc where c_id in(
select c_id from course as c
where t_id not in
(select t_id
from teacher
where t_name ='张三')));
# 方法2
select distinct (s.s_id),s_name from student as s
left join sc
on s.s_id =sc.s_id
left join course as c
on sc.c_id = c.c_id
left join teacher as t
on c.t_id = t.t_id
where t.t_name <>'张三' ;
6.查询学过张三老师所教的所有课程的同学的学号和姓名
select distinct (s.s_id),s_name from student as s
inner join sc
on s.s_id =sc.s_id
inner join course as c
on sc.c_id = c.c_id
inner join teacher as t
on c.t_id = t.t_id
where t.t_name = '张三';
7.查询学过01课程并且学过02课程的学生
select s.* from sc as sc1
inner join sc as sc2
on sc1.s_id =sc2.s_id
inner join student as s
on s.s_id=sc1.s_id
where sc1.c_id='01' and sc2.c_id='02';
8.查询学过02课程的总成绩
select sum(score) as sum
from sc
where c_id ='02';
9.查询所有课程成绩小于60的学生
select s.s_id from course as c
left join sc
on c.c_id =sc.c_id
left join student as s
on sc.s_id =s.s_id
group by s.s_id
having max(sc.score)<60;
10.查询没有学全所有课的学生学号、姓名
select s.s_id ,s_name from
student as s
inner join sc
on sc.s_id =s.s_id
inner join course as c
on sc.c_id =c.c_id
group by s.s_id ,s_name
having count(distinct c.c_id) <>(select count(*) from course);
11.查询至少有一门课与学号为“01”的学生所学课程相同的学生学号、姓名
# (1)查询学号为“01”的学生所学课程
select c_id from sc where s_id ='01';
# (2)查询课程号在 (1)里的学生号,不包括自己
select distinct s_id
from sc
where c_id in
(select c_id from sc where s_id ='01') and s_id<>'01';
# (3)根据学号查询对应信息
select s_id,s_name
from student
where s_id in
(select distinct s_id
from sc
where c_id in
(select c_id from sc where s_id ='01') and s_id<>'01');
12.查询和“01”学号学生所学课程完全相同的学生学号
#(1)查询学号为“01”的学生所学课程
select group_concat(c_id) as c_id_001
from sc group by s_id
having s_id='01';
# (2)查询课程号和(1)完全相同学生号,不包括自己
select s_id
from sc
where s_id <>'01'
group by s_id
having group_concat(c_id)=(select group_concat(c_id) as c_id_001
from sc group by s_id
having s_id='01');
# (3)根据学号查询对应信息
select s_id,s_name
from student
where s_id in (select s_id
from sc
where s_id <>'01'
group by s_id
having group_concat(c_id)=(select group_concat(c_id) as c_id_001
from sc group by s_id
having s_id='01'));
13.查询没学过"张三"老师讲授的任一门课程的学生姓名
select s.s_name
from teacher as t
left join course as c
on c.t_id=t.t_id
left join sc
on sc.c_id=c.c_id
left join student as s
on sc.s_id =s.s_id
where t_name is null or t_name <> '张三'
14.查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩
select s.s_id,s.s_name, round( avg(sc.score),1) average
from sc
inner join student as s
on s.s_id =sc.s_id
group by sc.s_id,s.s_name
having avg(sc.score)<60;
15.查询两门及其以上不及格的同学的学号、姓名和平均成绩
# (1)查询两门及其以上不及格的学生
select s_id
from sc where score<60
group by s_id
having count(score) >=2;
# (2)连接学生表和学生课程中间表 根据(1)的学生条件过滤
select s.s_id,s_name,round( avg(sc.score),1) as average_score from student as s
inner join sc
on s.s_id =sc.s_id
where s.s_id in (select s_id
from sc where score<60
group by s_id
having count(score) >=2)
group by s.s_id,s_name;
16.检索01课程分数小于60 ,按课程分数降序排列学生信息
select s.* ,sc.score from student as s
inner join sc
on s.s_id =sc.s_id
where sc.c_id='01' and sc.score<60
order by sc.score desc;
17.按平均成绩从高到低显示所有学生的所有课程的成绩和平均成绩
# (1)所有学生的所有课程的平均成绩
select s.s_id, round(avg(sc.score)) as average
from student as s
left join sc
on sc.s_id =s.s_id
group by s.s_id;
# (2)连接(1)和学生课程中间表,然后得到成绩,并按平均成绩从高到低显示
select temp.s_id,sc.score, temp.average_score
from sc
right join (select s.s_id, round(avg(sc.score)) as average_score
from student as s
left join sc
on sc.s_id =s.s_id
group by s.s_id) as temp
on sc.s_id =temp.s_id
order by temp.average_score desc;
18.查询各科成绩最高分、最低分、平均分、及格率、中等率、优良率、优秀率
#及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
#方法1:
select max(score) 最高分,min(score)最低分,round(avg(score),1)平均分 ,
concat( round(count(case when score>=60 then score end)/count(score)*100,1),'%') 及格率,
concat( round(count(case when score>=70 and score<80 then score end)/count(score)*100,1),'%') 中等率,
concat( round(count(case when score>=80 and score<90 then score end)/count(score)*100,1),'%') 优良率,
concat( round(count(case when score>=90 then score end)/count(score)*100,1),'%') 优秀率
from sc
group by c_id;
#方法2改进:
select max(score) 最高分,min(score)最低分,round(avg(score),1)平均分 ,
format(sum(case when score>=60 then 1 else 0 end)*100/nullif(count(score),0) ,1) as 及格率,
format(sum(case when score>=70 and score<80 then 1 else 0 end)*100/nullif(count(score),0) ,1) as 中等率,
format(sum(case when score>=80 and score<90 then 1 else 0 end)*100/nullif(count(score),0) ,1) as 优良率,
format(sum(case when score>=90 then 1 else 0 end)*100/nullif(count(score),0) ,1) as 优秀率
from sc
group by c_id;
19.按各科成绩进行排序,并显示排名
select row_number() over (order by sum(sc.score) desc) as 排名 ,coalesce( c.c_name,'无') as 科目, sum(sc.score)as 各科总分
from sc
left join course as c
on sc.c_id =c.c_id
group by sc.c_id, coalesce( c.c_name,'无')
20.查询学生的总成绩并进行排名
select s_id,sum(score) as 总成绩,row_number() over (order by sum(score) desc) as 排名
from sc group by s_id;
21.查询不同老师所教不同课程平均分从高到低展示
select t.t_id, c.c_id ,round(avg(sc.score),1) as average_score from teacher as t
inner join course as c
on t.t_id = c.t_id
inner join sc
on sc.c_id=c.c_id
group by t.t_id, c.c_id
order by average_score desc
22 .查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
# (1)查询所有课程的全部成绩排名的学生信息及该课程成绩
select c.c_id, s.*,sc.score,dense_rank() over (partition by sc.c_id order by sc.score) as _rank
from course as c
inner join sc on sc.c_id =c.c_id
inner join student as s on sc.s_id =s.s_id
# (2)过滤中成绩第二名和第三名的
select * from (select c.c_id, s.*,sc.score,dense_rank() over (partition by sc.c_id order by sc.score) as _rank
from course as c
inner join sc on sc.c_id =c.c_id
inner join student as s on sc.s_id =s.s_id) as rn
where rn._rank in (2,3);
23.使用分段来统计各科成绩,分别统计各分数段人数:课程ID和课程名称
# 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
# (1).为分数分配等级
select s_id,c_id, (case when score <60 then '不及格'
when score <70 then '及格'
when score <80 then '中等'
when score <90 then '优良'
else '优秀' end) as score_grade
from sc;
# (2)把(1)表和学生表连接并分区
select c.c_id,c.c_name, sg.score_grade,count(*) as num
from course as c
inner join (select s_id,c_id, (case when score <60 then '不及格'
when score <70 then '及格'
when score <80 then '中等'
when score <90 then '优良'
else '优秀' end) as score_grade
from sc) as sg on c.c_id =sg.c_id
group by c.c_id,c.c_name,sg.score_grade
order by c.c_id;
24.查询学生平均成绩以及排名
select s.s_id,round( avg(sc.score),1) as average_score,dense_rank() over (order by avg(sc.score) desc) as ranking from student as s
left join sc
on sc.s_id = s.s_id
group by s.s_id;
25.查询各科成绩前三名的记录(不考虑成绩并列情况)
select * from (select sc.c_id,sc.score,s.*,dense_rank() over (partition by sc.c_id order by sc.score desc) as _rank
from sc
left join student as s
on sc.s_id =s.s_id) as rt
where rt._rank <=3;
26.查询每门课程被选修的学生数
select c.c_id, count(sc.s_id) as num
from course as c
left join sc on c.c_id =sc.c_id
group by c.c_id;
27.查询出只有两门课程的全部学生的学号和姓名
# 方法1:(1)查询每个学生选得课的课程数
select s_id ,count(c_id)
from sc
group by s_id;
# (2)过滤中课数为2的学生并连接学生查询学生信息
select * from student as s
where s.s_id in(
select sc.s_id
from sc
group by sc.s_id
having count(sc.c_id) =2
);
# 方法2: 先连接学生和中间表得到全部学生的选得全部课程,然后按照学生分组,过滤出课程数为2的学生
select s.s_id,s.s_name,s.s_age,s.s_sex
from student as s
left join sc on s.s_id =sc.s_id
group by s.s_id,s.s_name,s.s_sex,s.s_age
having count(sc.c_id) =2;
28.查询男生、女生人数
select s_sex,count(*) from student
group by s_sex;
29. 查询名字中含有"三"字的学生信息
select *
from student
where s_name like '%三%'
30.查询同名同性学生名单,并统计同名同性人数
# (1)按照姓名、性别分组,可得到学生以及人数
select s_name,s_sex,count(*) as count
from student as s
group by s.s_name,s.s_sex
having count(*)>1;
# (2)以姓名性别为条件,把(1)连接学生表,查询对应学生记录
select s2.*,temp.count from student as s2
inner join (select s_name,s_sex,count(*) as count
from student as s
group by s.s_name,s.s_sex
having count(*)>1) as temp
on s2.s_name =temp.s_name and s2.s_sex =temp.s_sex;
31.查询1990年出生的学生名单
select *
from student where date_format(s_age,'%Y') =1990;
32.查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩
select sc.s_id, s.s_name, round(avg(score),1) as avg_score from sc
inner join student as s on s.s_id =sc.s_id
group by sc.s_id, s.s_name
having avg(sc.score)>=85;
33.查询每门课程的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列
select c_id,round(avg(score),1) as avg_score
from sc
group by c_id
order by avg_score asc,c_id desc;
34.查询课程名称为"数学",且分数低于60的学生姓名和分数
select s.s_name,sc.score
from student as s
inner join sc on s.s_id =sc.s_id
inner join course as c on c.c_id = sc.c_id
where c.c_name ='数学' and sc.score <60;
35.查询所有学生的课程及分数情况
select s.s_id,s.s_name,c.*,sc.score
from student as s
left join sc on s.s_id =sc.s_id
left join course as c on c.c_id = sc.c_id;
36.查询任何一门课程成绩在70分以上的姓名、课程名称和分数
select s.s_name,c.c_name, sc.score
from student as s
inner join sc on s.s_id =sc.s_id
inner join course as c on c.c_id = sc.c_id
where sc.score>70;
37.查询不及格的课程并按课程号从大到小排列
select c.* from course as c
left join sc on c.c_id = sc.c_id
where sc.score<60
order by c.c_id desc;
38.查询课程编号为03且课程成绩在80分以上的学生的学号和姓名
select s.s_id,s_name from student as s
inner join sc on s.s_id = sc.s_id
where sc.c_id ='03' and sc.score>80;
39.求每门课程的学生人数
select c_id ,count(s_id) as count from sc
group by c_id;
40.查询选修“张三”老师所授课程的学生中成绩最高的学生姓名及其成绩
select s.s_name,sc.score
from student as s
inner join sc on s.s_id =sc.s_id
where sc.score in (select max(sc.score)
from student as s
inner join sc on s.s_id =sc.s_id
inner join course as c on c.c_id = sc.c_id
inner join teacher as t on t.t_id =c.t_id
where t.t_name='张三'
group by c.c_id);
41.查询某个不同课程但成绩相同的学生编号、课程编号、学生成绩
# (1)查询不同课程但成绩相同的课程编号、学生成绩
select c_id ,score from sc
group by c_id,score
having COUNT(score)>1;
# (2)查询所求
select * from sc where (c_id,score) in (select c_id ,score from sc
group by c_id,score
having COUNT(score)>1);
42.查询每一门课程最好的前两名
# (1)按照课程分区,查询全部排名
select s.s_id,s.s_name ,sc.score ,dense_rank() over (partition by sc.c_id order by sc.score desc) as _rank
from student as s
inner join sc on s.s_id =sc.s_id
# (2)过滤出前2名
select *
from (select sc.c_id ,s.s_id,s.s_name ,sc.score ,dense_rank() over (partition by sc.c_id order by sc.score desc) as _rank
from student as s
inner join sc on s.s_id =sc.s_id)rn
where rn._rank<=2;
43.统计每门课程的学生选修人数(超过5人的课程才统计)。
要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
select c_id, count(s_id) as count from sc
group by c_id
having count >5
order by count desc ,c_id asc;
44.检索至少选修两门课程的学生学号
select s_id,count(c_id)
from sc
group by s_id
having count(c_id)>=2;
45.查询选修了全部课程的学生信息
# (1)查询全部课程的个数
select count(*)
from course;
# (2)查询选修全部个数学生
select s.s_id,s.s_name,s.s_age,s.s_sex,count(*) as num
from sc
left join student as s on s.s_id =sc.s_id
group by s.s_id,s.s_name,s.s_age,s.s_sex
having num =(select count(*)
from course);
46.查询各学生的年龄
# 方法1
select s_id, DATE_FORMAT(now(),'%Y') -DATE_FORMAT(s_age,'%Y') as age
from student;
# 方法2
select s_id, TIMESTAMPDIFF(YEAR,s_age,now() ) as age
from student;
47.查询本周过生日的学生
select * from student
where s_age between SUBDATE(now(),DATE_FORMAT(s_age,'%w')-1) and ADDDATE(now(),7-DATE_FORMAT(s_age,'%w'));
48.查询下周过生日的学生
select * from student
where s_age between ADDDATE(now(),DATE_FORMAT(s_age,'%w')+1) and ADDDATE(now(),7-DATE_FORMAT(s_age,'%w')+7);
49.查询本月过生日的学生
select * from student where DATE_FORMAT(s_age,'%m') =DATE_FORMAT(now(),'%m');
50.查询下月过生日的学生
select * from student where DATE_FORMAT(s_age,'%m') = DATE_FORMAT(TIMESTAMPADD(MONTH ,1,now()),'%m');
注解
1.union all是合并结果集(但 不去重,想要去重用union,性能没有union高),如1题
2.format 将数值格式化字符串,并保留几位。如18题
3.nullif(表达式1,表达式2)如果表达式相等,返回null ,不相等就返回第一个表达式 。可防止被零整除。如18题
4.coalesce(值1,值2,值…) 返回第一个非空值 ,如果都为空,则返回空。如19题
5.(1)row_number() over (order by sum(列) ) 根据指定列排序,并可以得到行的序号,如果值相同,序号不会并列。如20题
(2)rank() over () 类似row_number
但如果值相同,会并列排名,下一个会跳过这个排名(如并列第一 下一个第三)
(3)ENSE_RANK():与 RANK()
类似,但是不会跳过排名(例如,如果两行并列第一,则下一个排名是第二)。如22题
(4)partition by 定义窗口函数的分区
(5)over 定义窗口函数的操作,定义窗口函数的范围以及排序,决定窗口函数的功能