1. 建表
# 1、创建表
# 创建班级表
create table class(
cid int primary key auto_increment,
caption varchar(32) not null
);
# 创建学生表
create table student(
sid int primary key auto_increment,
gender char(1) not null,
class_id int not null,
sname varchar(32) not null,
foreign key(class_id) references class(cid) on delete cascade on update cascade
);
# 创建老师表
create table teacher(
tid int primary key auto_increment,
tname varchar(32) not null
);
# 创建课程表
create table course(
cid int primary key auto_increment,
cname varchar(32) not null,
teacher_id int not null,
foreign key(teacher_id) references teacher(tid) on delete cascade on update cascade
);
# 创建成绩表
create table score(
sid int primary key auto_increment,
student_id int not null,
course_id int not null,
num int not null,
foreign key(student_id) references student(sid) on delete cascade on update cascade,
foreign key(course_id) references course(cid) on delete cascade on update cascade
);
# 2、插入记录
# 班级表插入记录
insert into class values
('1', '三年二班'),
('2', '三年三班'),
('3', '一年二班'),
('4', '二年一班');
# 学生表插入记录
insert into student values
('1', '男', '1', '理解'),
('2', '女', '1', '钢蛋'),
('3', '男', '1', '张三'),
('4', '男', '1', '张一'),
('5', '女', '1', '张二'),
('6', '男', '1', '张四'),
('7', '女', '2', '铁锤'),
('8', '男', '2', '李三'),
('9', '男', '2', '李一'),
('10', '女', '2', '李二'),
('11', '男', '2', '李四'),
('12', '女', '3', '如花'),
('13', '男', '3', '刘三'),
('14', '男', '3', '刘一'),
('15', '女', '3', '刘二'),
('16', '男', '3', '刘四');
# 老师表插入记录
insert into teacher values
('1', '张磊'),
('2', '李平'),
('3', '刘海燕'),
('4', '朱云海'),
('5', '李春秋');
# 课程表插入记录
insert into course values
('1', '生物', '1'),
('2', '物理', '2'),
('3', '体育', '3'),
('4', '美术', '2');
# 成绩表插入记录
insert into score values
('1', '1', '1', '10'),
('2', '1', '2', '9'),
('3', '1', '3', '76'),
('5', '1', '4', '66'),
('6', '2', '1', '8'),
('8', '2', '3', '68'),
('9', '2', '4', '99'),
('10', '3', '1', '77'),
('11', '3', '2', '66'),
('12', '3', '3', '87'),
('13', '3', '4', '99'),
('14', '4', '1', '79'),
('15', '4', '2', '11'),
('16', '4', '3', '67'),
('17', '4', '4', '100'),
('18', '5', '1', '79'),
('19', '5', '2', '11'),
('20', '5', '3', '67'),
('21', '5', '4', '100'),
('22', '6', '1', '9'),
('23', '6', '2', '100'),
('24', '6', '3', '67'),
('25', '6', '4', '100'),
('26', '7', '1', '9'),
('27', '7', '2', '100'),
('28', '7', '3', '67'),
('29', '7', '4', '88'),
('30', '8', '1', '9'),
('31', '8', '2', '100'),
('32', '8', '3', '67'),
('33', '8', '4', '88'),
('34', '9', '1', '91'),
('35', '9', '2', '88'),
('36', '9', '3', '67'),
('37', '9', '4', '22'),
('38', '10', '1', '90'),
('39', '10', '2', '77'),
('40', '10', '3', '43'),
('41', '10', '4', '87'),
('42', '11', '1', '90'),
('43', '11', '2', '77'),
('44', '11', '3', '43'),
('45', '11', '4', '87'),
('46', '12', '1', '90'),
('47', '12', '2', '77'),
('48', '12', '3', '43'),
('49', '12', '4', '87'),
('52', '13', '3', '87');
# 表关系分析
class <=> student 关联: class_id
teacher <=> course 关联: teacher_id
score <=> student 关联: student_id
score <=> course 关联: course_id
2. 练习
1、查询所有的课程的名称以及对应的任课老师姓名
# where
select
course.cname,teacher.tname
from
teacher,course
where
teacher.tid = course.teacher_id
# inner join
select
course.cname,teacher.tname
from
teacher inner join course on teacher.tid = course.teacher_id
2、查询学生表中男女生各有多少人
select
gender,count(*)
from
student
group by
gender
3、查询物理成绩等于100的学生的姓名
# where
select
student.sname,score.num
from
student,score,course
where
score.student_id = student.sid
and
score.course_id = course.cid
and
score.num = 100
and
course.cname = '物理'
# inner join
select
student.sname,score.num
from
score inner join student on score.student_id = student.sid
inner join course on score.course_id = course.cid
where
course.cname = '物理'
and
score.num = 100
4、查询平均成绩大于八十分的同学的姓名和平均成绩
# where
select
student_id,student.sname,avg(num)
from
score,student
where
score.student_id = student.sid
group by
student_id
having
avg(num) > 80
# inner join
select
student_id,student.sname,avg(num)
from
score inner join student on score.student_id = student.sid
group by
student_id
having
avg(num) > 80
5、查询所有学生的学号,姓名,选课数,总成绩
# 选课数
select
student_id,count(*)
from
score
group by
student_id
# 总成绩
select
student_id,sum(num)
from
score
group by
student_id
# where
select
student_id,sname,count(*),sum(num)
from
score,student
where
score.student_id = student.sid
group by
student_id
# inner join
select
student_id,sname,count(*),sum(num)
from
score inner join student on score.student_id = student.sid
group by
student_id
# 附加所有学生
# right join
select
student.sid,sname,count(score.course_id),sum(num)
from
score right join student on score.student_id = student.sid
group by
student.sid
# left join
select
student.sid,sname,count(score.course_id),sum(num)
from
student left join score on student.sid = score.student_id
group by
student.sid
6、 查询姓李老师的个数
select
count(*)
from
teacher
where
tname like '李%'
select
group_concat(tname),count(*)
from
teacher
where
tname like '李%'
7、 查询没有报李平老师课的学生姓名
# 1. 报了李平老师课程的学生id
# distinct 去重 => distinct student | distinct(student)
select
distinct student_id
from
teacher,course,score
where
teacher.tid = course.teacher_id
and
course.cid = score.course_id
and
teacher.tname = '李平'
# 2. 查询学生表,反向找出没有报李平老师课程的学生id
select
student.sname
from
student
where
sid not in (1号数据)
# 3. 综合拼接
select
student.sname
from
student
where
sid not in (select
distinct student_id
from
teacher,course,score
where
teacher.tid = course.teacher_id
and
course.cid = score.course_id
and
teacher.tname = '李平' )
8、 查询物理课程的分数比生物课程的分数高的学生的学号
# where
# 1. 物理课程学生分数
select
student_id,num
from
score,course
where
score.course_id = course.cid
and
course.cname = '物理'
# 2. 生物课程学生分数
select
student_id,num
from
score,course
where
score.course_id = course.cid
and
course.cname = '生物'
# 3. 综合拼接
# 格式
'''
select
*
from
(1) inner join (2) on 1.student_id = 2.student_id
where
1.num > 2.num
'''
select
s1.student_id
from
(select
student_id,num
from
score,course
where
score.course_id = course.cid
and
course.cname = '物理') as s1 inner join
(select
student_id,num
from
score,course
where
score.course_id = course.cid
and
course.cname = '生物') as s2 on
s1.student_id = s2.student_id
where
s1.num > s2.num
# inner join
# 1. 物理课程学生分数
select
score.student_id , score.num , course.cid , course.cname
from
score inner join course on score.course_id = course.cid
where
course.cname = '物理'
# 2. 生物课程学生分数
select
score.student_id , score.num , course.cid , course.cname
from
score inner join course on score.course_id = course.cid
where
course.cname = '生物'
# 3. 综合拼接
select
s1.student_id
from
(select
score.student_id , score.num , course.cid , course.cname
from
score inner join course on score.course_id = course.cid
where
course.cname = '物理') as s1 inner join
(select
score.student_id , score.num , course.cid , course.cname
from
score inner join course on score.course_id = course.cid
where
course.cname = '生物') as s2 on s1.student_id = s2.student_id
where
s1.num > s2.num
# 学生姓名 学生学号 学生成绩
select
student.sname , s1.student_id , s1.num
from
student inner join (select
score.student_id , score.num , course.cid , course.cname
from
score inner join course on score.course_id = course.cid
where
course.cname = '物理') as s1 on student.sid = s1.student_id
inner join
(select
score.student_id , score.num , course.cid , course.cname
from
score inner join course on score.course_id = course.cid
where
course.cname = '生物') as s2 on s1.student_id = s2.student_id
where
s1.num > s2.num
9、 查询没有同时选修物理课程和体育课程的学生姓名
# 1. 找物理和体育的课程id
select
cid
from
course
where
cname = '物理'
or
cname = '体育'
# (2,3)
# 2. 选出选择物理和体育的学生 id
select
*
from
score
where
course_id in (2,3)
# 拼装数据
select
student_id
from
score
where
course_id in (select
cid
from
course
where
cname = '物理'
or
cname = '体育')
# 3. 同时学习物理和体育的学生 id
select
student_id
from
score
where
course_id in (select
cid
from
course
where
cname = '物理'
or
cname = '体育')
group by
score.student_id
having
count(*) = 2
# 4. 反向查询出没有同时学习物理和体育的学生id
select
sid,sname
from
student
where
sid not in (select
student_id
from
score
where
course_id in (select
cid
from
course
where
cname = '物理'
or
cname = '体育')
group by
score.student_id
having
count(*) = 2)
10、查询挂科超过两门(包括两门)的学生姓名和班级
# where
select
student_id , student.sname , class.caption
from
score , student , class
where
score.student_id = student.sid
and
student.class_id = class.cid
and
score.num < 60
group by
score.student_id
having
count(*) >= 2
# inner join
select
student_id , student.sname , class.caption
from
score inner join student on score.student_id = student.sid
inner join class on class.cid = student.class_id
where
num < 60
group by
student_id
having
count(*) >= 2
11、查询选修了所有课程的学生姓名
# 1. 统计所有课程总数
select count(*) from course
# where
# 2. 按照学生分类,总数量是课程总数,等价于学了所有课程
select
student_id , student.sname
from
score , student
where
score.student_id = student.sid
group by
student_id
having
count(*) = (select count(*) from course)
# inner join
select
student_id , sname
from
score inner join student on score.student_id = student.sid
group by
student_id
having
count(*) = (select count(*) from course)
12、查询李平老师教的课程的所有成绩记录
# 内联
select
score.student_id , course.cname , score.num
from
teacher , course , score
where
teacher.tid = course.teacher_id
and
course.cid = score.course_id
and
teacher.tname = '李平'
# 子查询
# 1. 找到李平老师的课程id
select
course.cid
from
teacher , course
where
teacher.tid = course.teacher_id
and
teacher.tname = '李平'
# 2. 通过课程 id 找出 score 里面的数据
select
*
from
score
where
score.course_id in (1号数据)
# 3. 综合拼接
select
score.student_id , score.num
from
score
where
score.course_id in (select
course.cid
from
teacher , course
where
teacher.tid = course.teacher_id
and
teacher.tname = '李平')
13、查询全部学生都选修了的课程号和课程名
# 1. 先查询有成绩的学生总数
select
count(distinct student_id)
from
score
# 2. 分组score中课程,统计单门课程被选的总数
select
course_id , count(*)
from
score
group by
course_id
# 3. 课程总数等于学生总数就是全部选修了的课程
select
course_id , course.cname
from
score , course
where
score.course_id = course.cid
group by
course_id
having
count(*) = (select
count(distinct student_id)
from
score)
14、查询每门课程被选修的次数
select
course_id , count(*)
from
score
group by
course_id
15、查询只选修了一门课程的学生学号和姓名
# where
select
student_id , student.sname
from
score , student
where
score.student_id = student.sid
group by
student_id
having
count(*) = 1
# inner join
select
student_id , student.sname
from
score inner join student on score.student_id = student.sid
group by
student_id
having
count(*) = 1
16、查询所有学生考出的成绩并按从高到低排序(成绩去重)
select
distinct num , group_concat(student_id)
from
score
group by
num
order by
num desc
select
num , group_concat(student_id)
from
score
group by
num
order by
num desc
select
distinct num num1
from
score
order by
num desc
17、查询平均成绩大于85的学生姓名和平均成绩
# 内联查询
select
student.sname , avg(num) num
from
score , student
where
score.student_id = student.sid
group by
student_id
having
avg(num) > 85
# 子查询
# 1. 查询出学生id
select
student_id , avg(num) num
from
score
group by
student_id
having
avg(num) > 85
# 2. 根据学生id找出学生姓名
select
sname
from
student
where
sid = (select
student_id
from
score
group by
student_id
having
avg(num) > 85)
# 3. 综合拼接
select
sname , t1.num
from
student inner join (select
student_id , avg(num) num
from
score
group by
student_id
having
avg(num) > 85) as t1 on student.sid = t1.student_id
18、查询生物成绩不及格的学生姓名和对应生物分数
# where
select
sname , num
from
score , student , course
where
score.student_id = student.sid
and
score.course_id = course.cid
and
course.cname = '生物'
and
score.num < 60
# inner join
select
sname , num , cname
from
score inner join course on score.course_id = course.cid
inner join student on score.student_id = student.sid
where
score.num < 60
and
course.cname = '生物'
19、查询在所有选修了李平老师课程的学生中,这些课程(李平老师的课程)平均成绩最高的学生姓名
# 内联
select
avg(num) avg_num , sname
from
score , course , teacher , student
where
teacher.tid = course.teacher_id
and
score.course_id = course.cid
and
score.student_id = student.sid
and
teacher.tname = '李平'
group by
student_id
order by
avg_num desc
limit 1
# 子查询
# 1. 找李平老师教的课程id
select
course.cid
from
teacher , course
where
teacher.tid = course.teacher_id
and
teacher.tname = '李平'
# 2. 学习李平老师课程的学生,按学生分类,找出平均分最高的id
select
student_id , avg(num)
from
score
where
student_id in (1号数据)
group by
score.student_id
order by
avg(num) desc limit 1
# 3. 通过学生id 连接student学生表,找出学生姓名
select
student_id , student.sname , avg(num)
from
score , student
where
score.student_id = student.sid
and
score.course_id in (1号数据)
group by
student_id
order by
avg(num) desc limit 1
# 4. 综合拼接
select
student_id , student.sname , avg(num)
from
score , student
where
score.student_id = student.sid
and
score.course_id in (select
course.cid
from
teacher , course
where
teacher.tid = course.teacher_id
and
teacher.tname = '李平')
group by
student_id
order by
avg(num) desc limit 1
20、查询每门课程成绩最好的课程id、学生姓名和分数
# 1. 找分数最大值
select
course_id , max(num) as max_num
from
score
group by
course_id
# 2. 找出该分数对应的学生
select
*
from
score as t1 inner join student as t2 on t1.student_id = t2.sid
inner join (1号数据) as t3 on t1.course_id = t3.course_id
# 3. 综合拼接
select
t1.course_id , t2.sname , t3.max_num
from
score as t1 inner join student as t2 on t1.student_id = t2.sid
inner join (select
course_id , max(num) as max_num
from
score
group by
course_id) as t3 on t1.course_id = t3.course_id
where
t1.num = t3.max_num
21、查询不同课程但成绩相同的课程号、学生号、成绩
# 不同的课程 如果使用 != 相同的数据返回来又查询了一遍,翻倍,为了防止翻倍重复查询,使用 < 或者 >
select
s1.student_id as s1_sid,
s2.student_id as s2_sid,
s1.course_id as s1_cid,
s2.course_id as s2_cid,
s1.num as s1_num,
s2.num as s2_num
from
score as s1 , score as s2
where
s1.course_id > s2.course_id
and
s1.num = s2.num
22、查询没学过“李平”老师课程的学生姓名以及选修的课程名称
# 查询李平老师教授的课程
select
distinct student_id
from
score , course , teacher
where
score.course_id = course.cid
and
course.teacher_id = teacher.tid
and
teacher.tname = '李平'
# 反向查询出没有报李平老师课程的学生
select
sname , sid
from
student
where
sid not in (select
distinct student_id
from
score , course , teacher
where
score.course_id = course.cid
and
course.teacher_id = teacher.tid
and
teacher.tname = '李平')
# 把没有选课的学生数据与成绩表和课程表再做一次联表
select
t1.sname , cname
from
score inner join course on score.course_id = course.cid
inner join (select
sname , sid
from
student
where
sid not in (select
distinct student_id
from
score , course , teacher
where
score.course_id = course.cid
and
course.teacher_id = teacher.tid
and
teacher.tname = '李平' )) as t1 on t1.sid = score.student_id
23、查询所有选修了学号为2的同学选修过的一门或者多门课程的同学学号和姓名
# 1. 先查询出学号为2的同学选修过的课程
select
course_id
from
score
where
student_id = 2
# 2. 再查询选修过的一门或者多门课程的同学学号和姓名
# where
select
distinct student_id , sname
from
score , student
where
course_id in (1号数据)
and
score.student_id = student.sid
# inner join
select
distinct student_id , sname
from
score inner join student on score.student_id = student.sid
where
course_id in (1号数据)
# 3. 综合拼接
# where
select
distinct student_id , sname
from
score , student
where
course_id in (select
course_id
from
score
where
student_id = 2)
and
score.student_id = student.sid
# inner join
select
distinct student_id , sname
from
score inner join student on score.student_id = student.sid
where
course_id in (select
course_id
from
score
where
student_id = 2)
24、任课最多的老师的学生单科成绩最高的课程id、学生姓名和分数
# 1. 先找出任课的最大数量
select
count(*)
from
course
group by
teacher_id
order by
count(*) desc limit 1
# 2. 找出最大任课数量的老师id
# 任课数量最多的老师可能不止一个
select
teacher_id
from
course
group by
teacher_id
having
count(*) = (1号数据)
# 3. 通过老师id找出课程
select
cid
from
course
where
teacher_id in (2号数据)
# 4. 通过课程id找出最高成绩
select
course_id , max(num) as max_num
from
score
where
course_id in (3号数据)
group by
course_id
# 5. 把对应的学生姓名,最大分数拼在一起,做一次单表查询
select
score.course_id , student.sname , t1.max_num
from
score inner join student on score.student_id = student.sid
inner join (4号数据) as t1 on t1.course_id = score.course_id
where
t1.max_num = score.num
# 6. 综合拼接
select
score.course_id , student.sname , t1.max_num
from
score inner join student on score.student_id = student.sid
inner join (select
course_id , max(num) as max_num
from
score
where
course_id in (select
cid
from
course
where
teacher_id in (select
teacher_id
from
course
group by
teacher_id
having
count(*) = (select
count(*)
from
course
group by
teacher_id
order by
count(*) desc limit 1)))
group by
course_id) as t1 on t1.course_id = score.course_id
where
t1.max_num = score.num
# 24题 巩固
# 任课最多的老师的学生单科成绩最高的课程id、学生姓名和分数
# 1. 先找出最大任课数量
select
count(*)
from
course
group by
teacher_id
order by
count(*) desc limit 1
# 2. 找出任课数量最多的老师id
select
teacher_id
from
course
group by
teacher_id
having
count(*) = (1号数据)
# 3. 通过老师id找出教授课程的id
select
cid
from
course
where
teacher_id in (2号数据)
# 4. 通过课程id找出最大成绩
select
course_id , max(num) as max_num
from
score
where
course_id in (3号数据)
group by
course_id
# 5. 通过最大成绩找出对应的课程id 学生姓名 最大分数
select
score.course_id , student.sname , t1.max_num
from
score inner join student on score.student_id = student.sid
inner join (4号数据) as t1 on score.course_id = t1.course_id
where
score.num = t1.max_num
# 6. 综合拼接
select
score.course_id , student.sname , t1.max_num
from
score inner join student on score.student_id = student.sid
inner join (select
course_id , max(num) as max_num
from
score
where
course_id in (select
cid
from
course
where
teacher_id in (select
teacher_id
from
course
group by
teacher_id
having
count(*) = (select
count(*)
from
course
group by
teacher_id
order by
count(*) desc limit 1) ))
group by
course_id) as t1 on score.course_id = t1.course_id
where
score.num = t1.max_num
# 24题 巩固
# 任课最多的老师的学生单科成绩最高的课程id、学生姓名和分数
# 1. 先查出最多任课数量
select
count(*)
from
course
group by
teacher_id
order by
count(*) desc limit 1
# 2. 根据最大任课数量找出老师id
select
teacher_id
from
course
group by
teacher_id
having
count(*) = (1号数据)
# 3. 根据老师id找出任课id
select
cid
from
course
where
teacher_id in (2号数据)
# 4. 根据任课id找出最大成绩
select
course_id , max(num) as max_num
from
score
where
course_id in (3号数据)
group by
course_id
# 5. 把最大成绩和课程id与学生姓名拼在一起,做一次单表查询
select
score.course_id , student.sname , t1.max_num
from
score inner join student on score.student_id = student.sid
inner join (4号数据) as t1 on score.course_id = t1.course_id
where
score.num = t1.max_num
# 6. 综合拼接
select
score.course_id , student.sname , t1.max_num
from
score inner join student on score.student_id = student.sid
inner join (select
course_id , max(num) as max_num
from
score
where
course_id in (select
cid
from
course
where
teacher_id in (select
teacher_id
from
course
group by
teacher_id
having
count(*) = (select
count(*)
from
course
group by
teacher_id
order by
count(*) desc limit 1)))
group by
course_id) as t1 on score.course_id = t1.course_id
where
score.num = t1.max_num