# where 筛选# group by 分组# having 过滤# distinct 去重# order by 排序# limit 分页# regexp 正则
今日内容概要
多表查询思路
navicat可视化软件
多表查询练习
python操作MySQL
其他理论补充
内容详细
1. 多表查询思路
# 准备数据 建表
create table dep(
idint primary key auto_increment,
name varchar(20)
);
create table emp(
idint primary key auto_increment,
name varchar(20),
sex enum('male','female') not null default 'male',
age int,
dep_id int
);
#插入数据
insert into dep values
(200,'技术'),
(201,'人力资源'),
(202,'销售'),
(203,'运营'),
(205,'保洁')
;
insert into emp(name,sex,age,dep_id) values
('jason','male',18,200),
('egon','female',48,201),
('kevin','male',18,201),
('nick','male',28,202),
('owen','male',18,203),
('jerry','female',18,204);
# 例:查询jason所在的部门名称"""涉及到SQL查询题目 一定要先明确到底需要几张表"""1.先查询jason所在的部门编号
select dep_id from emp where name='jason';
2.根据部门编号查询部门名称
select name from dep where id=(select dep_id from emp where name='jason');
"""
一条SQL语句的查询结果:
既可以看成是一张表
也可以看成是查询条件
"""# 多表查询的思路1.子查询
将SQL语句查询的结果括号括起来当做另外一条SQL语句的条件
大白话:就是我们日常生活中解决问题的方式>>>:分步操作
2.连表操作(重要)
先将需要使用到的表拼接成一张大表 之后基于单表查询完成
inner join 内连接
left join 左连接
right join 右连接
union 全连接
"""
涉及到多表查询的时候 字段名称容易冲突 需要使用表名点字段的方式区分
1.inner join:只拼接两张表中共有的部分
select * from emp inner join dep on emp.dep_id = dep.id;
2.left join:以左表为基准展示所有的内容 没有的NULL填充
select * from emp left join dep on emp.dep_id = dep.id;
3.right join:以右表为基准展示所有的内容 没有的NULL填充
select * from emp right join dep on emp.dep_id = dep.id;
4.union:左右表所有的数据都在 没有的NULL填充
select * from emp left join dep on emp.dep_id = dep.id
union
select * from emp right join dep on emp.dep_id = dep.id;
"""# 疑问:上述操作一次只能连接两张表 如何做到多张表?
将两张表的拼接结果当成一张表与跟另外一张表做拼接
依次往复 即可拼接多张表
# 1、查询所有的课程的名称以及对应的任课老师姓名
01 select * from teacher inner join course on teacher.tid=course.teacher_id; # 先找出所有课程表与老师表信息
02 select course.cname,teacher.tname from teacher inner join course on teacher.tid=course.teacher_id; # 再根据要求筛选出课程名称与对应任课老师# 2.查询平均成绩大于八十分的同学的姓名和平均成绩
先确定需要使用到的表
在思考多表查询的方式
# 先按学生编号分组
select student_id from score group by student_id;
# 再求平均成绩
select student_id,avg(num) from score group by student_id;
# 最后筛选出大于80的(针对聚合函数的字段结果 最好起别名防止冲突)
select student_id,avg(num) as avg_num from score group by student_id having(avg(num)>80);
# 整合 将上述SQL的结果与student表拼接
select student.sname,t1.avg_num from student inner join(select student_id,avg(num) as avg_num from score group by student_id having(avg(num)>80)) as t1 on student.sid=t1.student_id;
# 3.查询没有报李平老师课的学生姓名# 先查询李平老师教授的课程编号
select course.cid from course where teacher_id=(select tid from teacher where tname='李平老师');
# 再根据课程id号筛选出所有报了的学生id号
select student_id from score where course_id in (select course.cid from course where teacher_id=(select tid from teacher where tname='李平老师'));
# 最后去学生表中根据id号取反筛选学生姓名
select student.sname from student where sid notin(select distinct score.student_id from score where course_id in (select course.cid from course where teacher_id=(select tid from teacher where tname='李平老师')));
# 4.查询没有同时选修物理课程和体育课程的学生姓名(只要了报了一门的 两门和一门没报的都不要)# 先获取两门课程的id号
select course.cid from course where cname in ('物理','体育');
# 再去分数表中先筛选出所有报了物理和体育的学生id(两门 一门)
select * from score where course_id in (select course.cid from course where cname in ('物理','体育'));
# 如何筛选出只报了一门的学生id 按照学生id分组 然后计数 并过滤出计数结果为1的数据
select score.student_id from score where course_id in (select course.cid from course where cname in ('物理','体育')) group by score.student_id having count(score.course_id)=1;
# 根据学生id号去student表中筛选学生姓名
select student.sname from student where sid in (select score.student_id from score where course_id in (select course.cid from course where cname in ('物理','体育')) group by score.student_id having count(score.course_id)=1);
# 5.查询挂科超过两门(包括两门)的学生姓名和班级# 先筛选出小于60分的数据
select * from score where num<60;
# 按照学生id分组 然后统计挂科数量
select student_id,count(course_id) from score where num<60 group by student_id;
# 筛选出挂科超过两门的学生id
select student_id from score where num<60 group by student_id having count(course_id)>=2;
# 先将上述结果放在一边 去连接student和class表
select student.sname,class.caption fromclassinner join student on class.cid=student.class_id where student.sid in(select student_id from score where num<60 group by student_id having count(course_id)>=2);
# 更多练习
https://www.cnblogs.com/Dominic-Ji/p/10875493.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!