Mysql学习笔记——多表查询

1、概述

(1)一对多

(2)多对多

数据:

create table student(

id int auto_increment key comment '主键ID',

name varchar(10) comment '姓名',

no varchar(10) comment '学号'

)comment ' 学生表';

insert into student values (null,'黛绮丝','2000100101'),(null,'谢逊','2000100102'),(null,'殷天正','2000100103'),(null,'韦一笑','2000100104');

create table course(

id int auto_increment key comment '主键ID',

name varchar(10) comment '课程名称'

)comment '课程表';

insert into course values (null,'Java'),(null,'PHP'),(null,'Mysql'),(null,'Hadoop');

create table student_course(

id int auto_increment comment '主键' key,

studentid int not null comment '学生ID',

courseid int not null comment '课程ID',

constraint fk_courseid foreign key (courseid) references course(id),

constraint fk_studentid foreign key (studentid) references student(id)

)comment '学生课程中间表';

insert into student_course values (null,1,1),(null,1,2),(null,1,3),(null,2,3),(null,3,4);

创建了学生表、课程表以及两个表之间的关联表,一下主要通过id进行关联

(3)一对一

数据:

复制代码
create table tb_user(
  id int auto_increment  key COMMENT '主键ID',

  name varchar(10) COMMENT '姓名',

  age int COMMENT '年龄',

  gender char(1) COMMENT '1:男, 2:女',

  phone char(11) COMMENT '手机号'

)comment '用户基本信息表';

create table tb_user_edu(
  id int auto_increment primary key COMMENT '主键ID',

  degree varchar(20) COMMENT '学历',

  major varchar(50) COMMENT '专业',

  primaryschool varchar(50) COMMENT '小学',

  middleschool varchar(50) COMMENT '中学',

  university varchar(50) COMMENT '大学',

  userid int unique COMMENT '用户ID',

  constraint fk_userid foreign key (userid) references tb_user(id)

)comment '用户教育信息表';

insert into tb_user(id,name,age,gender,phone) values

(null,'黄渤',45,'1','18800001111'),

(null,'冰冰',35,'2','18800002222'),

(null,'码云',55,'1','18800008888' ),

(null,'李彦宏',50,'1','18800009999');

insert into tb_user_edu(id, degree, major, primaryschool, middleschool, university, userid) values

(null,'本科','舞蹈','静安区第一小学','静安区第一中学','北京舞蹈学院',1),

(null,'硕士','表演','朝阳区第一小学','朝阳区第一中学','北京电影学院',2),

(null,'本科','英语','杭州市第一小学','杭州市第一中学','杭州师范大学',3),

(null,'本科','应用数学','阳泉第一小学','阳泉区第一中学','清华大学',4);

2、多表查询

复制代码
select * from empp,dept where empp.dept_id=dept.id;

加上一个条件即可消除

(1)内连接

习题:(a)

复制代码
select empp.name,dept.name from empp,dept where empp.dept_id=dept.id;

(b)

复制代码
select empp.name,dept.name from empp join dept on empp.dept_id=dept.id;

结果依然如上所示

同一个题的两种显示方式!!!

(2)外连接

以左连接为例,将A和B连接之后,如果选择左连接,就返回A表和B表相连接之后的整个信息表,并且以A表的数据为主,B表如果没有A表相对应的内容就置为NULL

习题:(a)

复制代码
select empp.*,dept.name from empp left join dept on empp.dept_id=dept.id;

(b)

复制代码
select dept.*,empp.* from empp right join dept on empp.dept_id=dept.id;

(3)自连接

习题:(a)

复制代码
select a.name,b.name from empp a join empp b on a.managerid=b.id;

自连接的时候最好起别名,不然不太好区分

(b)

复制代码
select a.name,b.name from empp a left join empp b on a.managerid=b.id;

(4)联合查询

习题:

复制代码
select * from empp where salary<10000
union all
select * from empp where age>50;

这里因为表的数据较少,因此将薪资改为10000,题目的意思是将薪资低于10000的和年龄大于50的都罗列出来,使用union all实现这个功能

并且union的时候只要上面符合条件的人出现过一次,下面的表就不显示

union all则相当于上面一个表,下面一个表,将两个表进行拼接得到的

并且上下两个字段列表的数量要一致

(5)子查询

(a)标量子查询

习题:(a)

复制代码
select id from dept where name='销售部';#先查找销售部的部门id
select * from find where dept_id=4;#一一对应将属于销售部的员工信息进行罗列

(b)

复制代码
select * from find where entrydate>(select entrydate from find where name='方东白');

(b)列子查询

习题:(a)

复制代码
select * from find where dept_id in(select id from dept where name='销售部' or name='市场部');

(b)查询条件都满足才返回

复制代码
select * from find where salary>(select max(salary) from find where dept_id=(select id from dept where name='财务部' ));

或者:

(c)任意一个满足条件就返回

复制代码
select * from find where salary >any(select salary from find where dept_id=(select id from dept where name='研发部'));

(c)行子查询

习题:返回结果为一行多列!

复制代码
select * from find where (salary,managerid)=(select salary,managerid from find where name='张无忌');

(d)表子查询

习题:(a)多行多列对应,在上述的基础上将等号变成in,代表只要有一个满足即可!!!

复制代码
select * from find where (job,salary) in (select job,salary from find where name ='鹿杖客'or name='宋远桥');

(b)直接将中间的表放到from后面进行查询!

复制代码
select * from(select * from find  where entrydate>'2006-01-01') f left join dept on f.dept_id=dept.id;

3、综合练习1

(1)

复制代码
select f.name,f.age,f.job,d.name from find f,dept d where f.dept_id=d.id;

(2)

复制代码
select f.name,f.age,f.job,d.name from find f join dept d on (f.dept_id=d.id) where age<30;

(3)

使用distinct可以去除重复的结果

复制代码
select distinct d.id,d.name from find f , dept d where f.dept_id=d.id;

(4)一定要注意where后边首先就对数据进行初次删除,如果和on后面的条件互换,那么没有分配部分的员工是展示不出来的,因为在初筛的时候就去掉了!!!

复制代码
select f.*,d.name from find f left join dept d on f.dept_id=d.id where age>40;

(5)

复制代码
select f.name,s.grade from find f,salgrade s where f.salary>=s.losal and f.salary<=s.hisal;

(6)

复制代码
select f.*,s.grade from (select * from find f where dept_id=(select id from dept where name='研发部')) f,salgrade s where (f.salary between s.losal and s.hisal);

(7)

复制代码
select avg(f.salary)
from find f,
     dept d
where f.dept_id = (select id from dept where name = '研发部');

(8)

复制代码
select * from find f where salary>(select salary from find where name='灭绝');

(9)

复制代码
select * from find where salary>(select avg(salary) from find);

(10)

复制代码
select * from find f where f.salary<(select avg(i.salary) from find i where i.dept_id=f.dept_id);

(11)

复制代码
select id,name,(select count(*)from find f where f.dept_id=d.id)'人数' from dept d;

先查询dept表中的部门信息,之后在展示部分新增一个人数的信息,将每个部门的人数添加进去即可

(12)

复制代码
select s.name '姓名',s.no '学号',c.name '课程名' from student s,course c,student_course sc where sc.studentid=s.id and sc.courseid=c.id;

总结:

相关推荐
Lhappy嘻嘻10 分钟前
Java IO|File 文件操作 + 字节流 / 字符流完整笔记 + 递归删除文件实战
java·笔记·php
GLDbalala3 小时前
GPU PRO 5 - 4.6 Adaptive Scalable Texture Compression 笔记
笔记
xian_wwq3 小时前
【学习笔记】模型权重管理:Safetensors与私有化Hub(23/35)
笔记·学习
其实防守也摸鱼3 小时前
运维--学习阶段问题解答(1)(自测)
linux·运维·服务器·数据库·学习·自动化·命令模式
ctrl_v助手3 小时前
Halcon学习笔记2
人工智能·笔记·学习
YUS云生4 小时前
Python学习笔记·第31天:FastAPI入门——路由、路径参数、查询参数与请求体
笔记·python·学习
玖玥拾4 小时前
C# 语言进阶(十五)C# 游戏服务端 MySQL 数据库
服务器·开发语言·网络·数据库·mysql·c#
铅笔侠_小龙虾5 小时前
Rust 学习目录
开发语言·学习·rust
一个有温度的技术博主6 小时前
【VulnHub 实战】DC-1 靶机渗透测试笔记(一):信息收集与主机发现
服务器·网络·笔记