MySQL-实例练习

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
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I believe I can fly~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值