11、求每门课程的学生人数及平均分,输出课程编号、对应学生人数、平均分
SELECT
course_id,
count( DISTINCT student_id ) AS student_count,
avg( score ) AS avg_score
FROM
score
GROUP BY
course_id
12、求每门课程的学生人数及平均分,输出课程名称、对应学生人数、平均分
方法一
SELECT
co.NAME,
co.course_id,
count( DISTINCT sc.student_id ) AS student_count,
avg( sc.score ) AS avg_score
FROM
score sc
JOIN course co ON sc.course_id = co.course_id
GROUP BY
co.NAME,
co.course_id
方法二
select a.name
,a.course_id
,b.student_count
,b.avg_score
from
(
select *
from course
) a
join
(
select course_id
,count(*) as student_count
,avg(score) as avg_score
from score
group by course_id
) b
on a.course_id = b.course_id
13、查询同时学习" 01 "课程和" 02 "课程的学生编号及01和02课程分数
方法一:列存储
SELECT
student_id,
score,
course_id
from score
where course_id in ('01','02')
方法二:行存储,自关联
select a.student_id
,a.score as score_01
,b.score as score_02
from
(
select *
from score
where course_id = '01'
) a
join
(
select *
from score
where course_id = '02'
) b
on a.student_id = b.student_id;
14、查询" 01 "课程比" 02 "课程成绩高的学生编号及01和02课程分数
SELECT
a.student_id,
a.score AS score_01,
b.score AS score_02
FROM
( SELECT * FROM score WHERE course_id = '01' ) a
JOIN ( SELECT * FROM score WHERE course_id = '02' ) b ON a.student_id = b.student_id
WHERE
a.score > b.score
select a.student_id
,a.score as score_01
,b.score as score_02
from
(
select *
from score
where course_id = '01'
) a
join
(
select *
from score
where course_id = '02'
) b
on a.student_id = b.student_id
where a.score > b.score
15、查询" 01 "课程比" 02 "课程成绩高的学生姓名及01和02课程分数
写法一
select c.name
,a.score as score_01
,b.score as score_02
from
(
select *
from score
where course_id = '01'
) a
join
(
select *
from score
where course_id = '02'
) b
on a.student_id = b.student_id
join (
select *
from student
) c
on a.student_id = c.student_id
where a.score > b.score
写法2:
select name
,score_01
,score_02
from
(
select *
from student
) a
join
(
select a.student_id
,a.score as score_01
,b.score as score_02
from
(
select *
from score
where course_id = '01'
) a
join
(
select *
from score
where course_id = '02'
) b
on a.student_id = b.student_id
where a.score > b.score
) b
on a.student_id=b.student_id
- 连续三道题都是有关联的,前两道题给这道题做铺垫,所以当我们拿到一个向这种比较复杂的需求时,可以进行拆分需求,先拆分成1、在做2,最后达到完整的需求。
16、查询选择了 "01"课程但没选择 "02"课程的学生姓名(同一个字段,取不同值时,用left join )
错误写法:
SELECT
a.NAME,
b.course_id
FROM
student a
JOIN score b ON a.student_id = b.student_id
WHERE
b.course_id = '01'
AND b.course_id <> '02';
----"b.course_id <> '02'" 该条件不起作用
写法二:
-
-- 找出选择了 "01"课程但没选择 "02"课程的学生编号 select a.student_id from ( select * from score where course_id = '01' ) a left outer join ( select * from score where course_id = '02' ) b on a.student_id = b.student_id where b.student_id is null
-- 拿着学生编号关联学生表找到姓名 select name from ( select a.student_id as student_id from ( select * from score where course_id = '01' ) a left outer join ( select * from score where course_id = '02' ) b on a.student_id = b.student_id where b.student_id is null ) a join ( select * from student ) b on a.student_id = b.student_id
- 首先我们先找出选择了 "01"课程但没选择 "02"课程的学生编号,再拿着学生编号关联学生表找到姓名即可
17、查询学过 '张三' 老师课程的所有同学姓名、生日、性别
写法一
SELECT
g.*
FROM
(
SELECT
e.student_id
FROM
(
SELECT
b.course_id,
c.teacher_id,
c.NAME
FROM
course b
JOIN ( SELECT teacher_id, NAME FROM teacher WHERE NAME = '张三' ) c ON b.teacher_id = c.teacher_id
) d
JOIN ( SELECT student_id, course_id FROM score ) e ON d.course_id = e.course_id
) f
JOIN ( SELECT * FROM student ) g ON f.student_id = g.student_id
写法二
select b.*
from
(
select student_id
from
(
select course_id
from
(
select teacher_id
from teacher
where name='张三'
) a
join
(
select course_id
,teacher_id
from course
) b
on a.teacher_id = b.teacher_id
) a
join
(
select student_id
,course_id
from score
) b
on a.course_id = b.course_id
group by student_id
) a
join
(
select *
from student
) b
on a.student_id = b.student_id
找出 '张三' 老师的教师编号
找出 '张三' 老师所有教授的课程编号
找出这些课程对应的学生编号
根据学生编号找到对应的学生信息
解题思路
根据上述四个步骤,依次书写 SQL
18、查询同时学习 "01"、"02"课程学生的学生编号以及"01"和"02"课程成绩
SELECT
a.student_id,
a.score AS score_01,
b.score AS score_02
FROM
( SELECT * FROM score WHERE course_id = '01' ) a
JOIN ( SELECT * FROM score WHERE course_id = '02' ) b ON a.student_id = b.student_id
select a.student_id as student_id
,a.score as score_01
,b.score as score_02
from
(
select *
from score
where course_id = '01'
) a
join
(
select *
from score
where course_id = '02'
) b
on a.student_id = b.student_id;
19、查询学习 "01"课程但没有学习 "02"课程学生的学生编号以及"01"课程成绩
select a.student_id as student_id
,a.score as score_01
,b.score as score_02
from
(
select *
from score
where course_id = '01'
) a
left join
(
select *
from score
where course_id = '02'
) b
on a.student_id = b.student_id
where b.course_id is null;
select a.student_id as student_id
,a.score as score_01
from
(
select *
from score
where course_id = '01'
) a
left outer join
(
select *
from score
where course_id = '02'
) b
on a.student_id = b.student_id
where b.student_id is null
20、查询学习 "02"课程但没有学习 "01"课程学生的学生编号以及"02"课程成绩
select b.student_id as student_id
,a.score as score_01
,b.score as score_02
from
(
select *
from score
where course_id = '01'
) a
right join
(
select *
from score
where course_id = '02'
) b
on a.student_id = b.student_id
where a.course_id is null;
select b.student_id as student_id
,b.score as score_02
from
(
select *
from score
where course_id = '01'
) a
right outer join
(
select *
from score
where course_id = '02'
) b
on a.student_id = b.student_id
where a.student_id is null
21、查询选课的同学的学生姓名、选课总数、所有课程的成绩总和、课程平均分
SELECT
a.NAME,
course_num,
score_sum,
score_avg
FROM
( SELECT student_id, NAME FROM student ) a
JOIN (
SELECT
student_id,
count( course_id ) AS course_num,
sum( score ) AS score_sum,
round( avg( score ), 2 ) AS score_avg
FROM
score
GROUP BY
student_id
) b ON a.student_id = b.student_id
ORDER BY
course_num DESC,
score_sum DESC
select a.name as name
,course_num
,score_sum
,score_avg
from
(
select student_id
,name
from student
) a
join
(
select student_id
,count(course_id) as course_num
,sum(score) as score_sum
,avg(score) as score_avg
from score
group by student_id
) b
on a.student_id=b.student_id
order by course_num desc
,score_sum desc
22、查询考试平均分大于 60 分同学的学生姓名、选课总数、所有课程的成绩总和、课程平均分,按照科目数排降序、科目数相同按照分数排降序
select a.name as name
,course_num
,score_sum
,score_avg
from
(
select student_id
,name
from student
) a
join
(
select student_id
,count(course_id) as course_num
,sum(score) as score_sum
,avg(score) as score_avg
from score
group by student_id
having avg(score) > 60
) b
on a.student_id=b.student_id
order by course_num desc
,score_sum desc
select a.name as name
,course_num
,score_sum
,score_avg
from
(
select student_id
,name
from student
) a
join
(
select student_id
,count(course_id) as course_num
,sum(score) as score_sum
,avg(score) as score_avg
from score
group by student_id
) b
on a.student_id=b.student_id
where score_avg > 60
order by course_num desc
,score_sum desc
23、检索 "01" 课程分数小于 60 分的学生信息及"01" 课程分数,按照分数排降序
select
b.*
,a.score_01
from
( select
student_id
,score as score_01
from score
where course_id='01'
) a
left join
( SELECT
*
from student
) b
on a.student_id = b.student_id
where a.score_01 < 60
order by a.score_01 desc
select a.student_id as student_id
,name
,birthday
,sex
,score
from
(
select *
from student
) a
join
(
select student_id
,score
from score
where course_id='01'
and score < 60
) b
on a.student_id = b.student_id
order by score desc
24、查询两门及其以上不及格课程的同学的姓名及其平均成绩
写法一
SELECT
b.NAME,
a.score_avg
FROM
( SELECT student_id, avg( CASE WHEN score < 60 THEN score ELSE NULL END ) AS score_avg FROM score GROUP BY student_id ) a
JOIN ( SELECT student_id, NAME FROM student ) b ON a.student_id = b.student_id
WHERE
a.score_avg IS NOT NULL
写法二
select name
,score_avg
from
(
select *
from student
) a
join
(
select student_id
,score_avg
from
(
select student_id
,avg(score) as score_avg
,count(case when score < 60 then 1 end) as fail_count
from score
group by student_id
) a
where fail_count > 1
) b
on a.student_id = b.student_id
;