接上第二篇。
21.查询男生、女生人数
22.查询名字中含有「风」字的学生信息
23.查询同名同性学生名单,并统计同名人数
24.查询 1990 年出生的学生名单
25.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
26.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
27.查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
28.查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
29.查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
30.查询不及格的课程
31.查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名
32.求每门课程的学生人数
33.成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
34.成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
35.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
36.查询每门功成绩最好的前两名
37.统计每门课程的学生选修人数(超过 5 人的课程才统计)。
38.检索至少选修两门课程的学生学号
39.查询选修了全部课程的学生信息
40.查询各学生的年龄,只按年份来算
41.按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
42.查询本周过生日的学生
43.查询下周过生日的学生
44.查询本月过生日的学生
45.查询下月过生日的学生
21.查询男生、女生人数
select ssex, count(*) from student
group by ssex;
22.查询名字中含有「风」字的学生信息
select *
from student
where student.Sname like '%风%'
23.查询同名学生名单,并统计同名人数
找到同名的名字并统计个数
select sname, count(*) from student
group by sname
having count(*)>1;
嵌套查询列出同名的全部学生的信息
select * from student
where sname in (
select sname from student
group by sname
having count(*)>1
);
24.查询 1990 年出生的学生名单
select *
from student
where YEAR(student.Sage)=1990;
25.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
select sc.cid, course.cname, AVG(SC.SCORE) as average from sc, course
where sc.cid = course.cid
group by sc.cid
order by average desc,cid asc;
26.查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩
having也可以用来截取结果表,在这里就先得到平均成绩总表,再截取AVG大于85的即可.
select student.sid, student.sname, AVG(sc.score) as aver from student, sc
where student.sid = sc.sid
group by sc.sid
having aver > 85;
27.查询课程名称为「数学」,且分数低于 60 的学生姓名和分数
select student.sname, sc.score from student, sc, course
where student.sid = sc.sid
and course.cid = sc.cid
and course.cname = "数学"
and sc.score < 60;
28.查询所有学生的课程及分数情况(存在学生没成绩,没选课的情况)
select student.sname, cid, score from student
left join sc
on student.sid = sc.sid;
29.查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数
select student.sname, course.cname,sc.score from student,course,sc
where sc.score>70
and student.sid = sc.sid
and sc.cid = course.cid;
30.查询存在不及格的课程
可以用group by 来取唯一,也可以用distinct
select cid from sc
where score< 60
group by cid;
select DISTINCT sc.CId
from sc
where sc.score <60;
31.查询课程编号为 01 且课程成绩在 80 分及以上的学生的学号和姓名
select student.sid,student.sname
from student,sc
where cid="01"
and score>=80
and student.sid = sc.sid;
32.求每门课程的学生人数
select sc.CId,count(*) as 学生人数
from sc
GROUP BY sc.CId;
33.成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
用having max()理论上也是对的,但是下面那种按分数排序然后取limit 1的更直观可靠
select student.*, sc.score, sc.cid from student, teacher, course,sc
where teacher.tid = course.tid
and sc.sid = student.sid
and sc.cid = course.cid
and teacher.tname = "张三"
having max(sc.score);
select student.*, sc.score, sc.cid from student, teacher, course,sc
where teacher.tid = course.tid
and sc.sid = student.sid
and sc.cid = course.cid
and teacher.tname = "张三"
order by score desc
limit 1;
34.成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
为了验证这一题,先修改原始数据
UPDATE sc SET score=90
where sid = "07"
and cid ="02";
这样张三老师教的02号课就有两个学生同时获得90的最高分了。
这道题的思路继续上一题,我们已经查询到了符合限定条件的最高分了,这个时候只用比较这张表,找到全部score等于这个最高分的记录就可,看起来有点繁复。
select student.*, sc.score, sc.cid from student, teacher, course,sc
where teacher.tid = course.tid
and sc.sid = student.sid
and sc.cid = course.cid
and teacher.tname = "张三"
and sc.score = (
select Max(sc.score)
from sc,student, teacher, course
where teacher.tid = course.tid
and sc.sid = student.sid
and sc.cid = course.cid
and teacher.tname = "张三"
);
35.查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
同上,在这里用了inner join后会有概念是重复的记录:“01 课与 03课”=“03 课与 01 课”,所以这里取唯一可以直接用group by
select a.cid, a.sid, a.score from sc as a
inner join
sc as b
on a.sid = b.sid
and a.cid != b.cid
and a.score = b.score
group by cid, sid;
36.查询每门功成绩最好的前两名
同上19题
select a.sid,a.cid,a.score from sc as a
left join sc as b
on a.cid = b.cid and a.score<b.score
group by a.cid, a.sid
having count(b.cid)<2
order by a.cid;
37.统计每门课程的学生选修人数(超过 5 人的课程才统计)
select sc.cid, count(sid) as cc from sc
group by cid
having cc >5;
38.检索至少选修两门课程的学生学号
select sid, count(cid) as cc from sc
group by sid
having cc>=2;
39.查询选修了全部课程的学生信息
select student.*
from sc ,student
where sc.SId=student.SId
GROUP BY sc.SId
HAVING count(*) = (select DISTINCT count(*) from course )
40.查询各学生的年龄,只按年份来算
不想做,一般都用41题的方法精确到天
按照出生日期来算,当前月日 < 出生年月的月日则,年龄减一
select student.SId as 学生编号,student.Sname as 学生姓名,
TIMESTAMPDIFF(YEAR,student.Sage,CURDATE()) as 学生年龄
from student
42.查询本周过生日的学生
select *
from student
where WEEKOFYEAR(student.Sage)=WEEKOFYEAR(CURDATE());
43.查询下周过生日的学生
select *
from student
where WEEKOFYEAR(student.Sage)=WEEKOFYEAR(CURDATE())+1;
44.查询本月过生日的学生
select *
from student
where MONTH(student.Sage)=MONTH(CURDATE());
45.查询下月过生日的学生
select *
from student
where MONTH(student.Sage)=MONTH(CURDATE())+1;