【题目总览】

19.查询每门课程被选修的学生数

20.查询出只选修两门课程的学生学号和姓名

21.查询男生、女生人数

22.查询名字中含有[风]字的学生信息

23.查询同名同姓学生名单,并统计同名同性人数

24.查询1990年出生的学生名单

25.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同,按课程编号升序排列

26.查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩

27.查询课程名称为[数学],且分数低于60的学生姓名和分数 

19.查询每门课程被选修的学生数
【分析】按照课程id分组统计数据量 

SELECT sc.cid 课程编号,c.cname 课程名称,COUNT(sc.cid) 选修人数
FROM sc
LEFT JOIN course c
ON sc.cid = c.cid
GROUP BY sc.cid;

20.查询出只选修两门课程的学生学号和姓名
【分析】分组查询,根据分组情况进行筛选 

SELECT sc.sid 学生编号,s.sname 学生姓名,COUNT(sc.cid) 选课数量
FROM sc
LEFT JOIN student s
ON sc.sid = s.sid
GROUP BY sc.sid
HAVING COUNT(sc.cid) = 2;

21.查询男生、女生人数
【分析】根据性别分组即可

# 法一
SELECT ssex 性别,COUNT(sid) 人数
FROM student
GROUP BY ssex;

# 法二
SELECT ssex 性别,COUNT(1) 人数
FROM student
GROUP BY ssex;

22.查询名字中含有[风]字的学生信息

SELECT *
FROM student 
WHERE sname LIKE '%风%';

23. 查询同名同姓学生名单,并统计同名同性人数
【分析】自关联筛选出符合条件的记录,要求名字、性别相等,但是sid不同

SELECT a.sname 姓名,a.ssex 性别,COUNT(a.sid) 同名人数
FROM student a
INNER JOIN student b
ON a.sname = b.sname AND a.ssex = b.ssex AND a.sid != b.sid
GROUP BY a.sname,a.ssex;


SELECT a.sname 姓名,a.ssex 性别,COUNT(1) 同名人数
FROM student a
INNER JOIN student b
ON a.sname = b.sname AND a.ssex = b.ssex AND a.sid != b.sid
GROUP BY a.sname,a.ssex;

24.查询1990年出生的学生名单
【分析】关键字段“出生日期sage”,year函数

SELECT *
FROM student
WHERE YEAR(sage) = 1990;

25.查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同,按课程编号升序排列

select a.cid,b.cname,avg(a.score) as avg_score
from sc a
left join course b
on a.cid = b.cid
group by a.cid
order by avg_score desc,a.cid asc;

26.查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩
【分析】需要分组聚合求得平均值,然后筛选学生信息

select a.sid,b.sname,avg(a.score) as avg_score
from sc a
left join student b
on a.sid = b.sid
group by a.sid
having avg_score >= 85;

27.查询课程名称为[数学],且分数低于60的学生姓名和分数 
【分析】条件关联查询 

# 法一
-- 1、先查询数学的课程id --
select cid
from course
where cname ='数学';
-- 2、筛选分数低于60分的成绩记录 --
select sid,score
from sc 
where cid in (select cid
from course
where cname ='数学') and score < 60;
-- 
select 
    a.sid,
    cid,
    b.sname,
    a.score
from sc a
left join student b
on a.sid=b.sid
where cid = (select cid from course where cname ='数学') and score<60;

# 法二
-- 1.先筛选出课程名称为数学且分数低于60的sid和score --
SELECT sid,score,c.cname,c.cid
FROM course c
LEFT JOIN sc
ON c.cid = sc.cid
WHERE c.cname = '数学' AND score < 60;
-- 2.将以上结果与学生表student关联 --
SELECT s.sname,a.cid,a.cname,a.score
FROM student s
RIGHT JOIN (SELECT sid,score,c.cname,c.cid
FROM course c
LEFT JOIN sc
ON c.cid = sc.cid
WHERE c.cname = '数学' AND score < 60) a
ON s.sid = a.sid;