前言
⭐Hello!这里是欧_aita的博客。
⭐今日语录:生活中最大的挑战就是发现自己是谁。然后,坚定不移地成为那个人。
⭐个人主页:欧_aita
ψ(._. )>⭐个人专栏:
数据结构与算法
MySQL数据库
多表查询
- 前言
- 多表关系
- 概述🚀
- 一对多🚀
- 多对多🚀
- 一对一🚀
- 多表查询概述
- 连接查询🐍
- 内连接🕷
- 隐式内连接
- 代码实战
- 效果图
- 显式内连接
- 实战代码
- 效果图
- 外连接🕷
- 左外连接
- 实战代码
- 效果图
- 右外连接
- 实战代码
- 效果图
- 自连接🕷
- 实战代码
- 效果图
- 联合查询--union,union all🐍
- 实战代码
- 效果图
- 注意点🕷
- 子查询🕷
- 标量子查询
- 实战代码
- 效果图
- 列子查询
- 实战代码
- 效果图
- 行子查询
- 实战代码
- 效果图
- 表子查询
- 实战代码
- 效果图
多表关系
概述🚀
项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模板之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在各种联系,基本上分为三种:
1. 一对多
2. 多对多
3. 一对一
一对多🚀
一个部门对应多个员工,在多的一方建立外键,指向一的一方的主键。
多对多🚀
学生与课程之间的关系。建立第三张中间表,中间表至少包含两个外键,分别关联两方主键。
create table student(id int auto_increment primary 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 primary 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 '主键' primary 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,2),(null,2,3),(null,3,4);
展示多对多关系图片
1.学生
2.课程
3.将同学与课程连接起来==(多对多的关系体现)==
一对一🚀
用户与用户详情的关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率。
在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的
create table tb_user(id int auto_increment primary 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);
多表查询概述
设定两个集合A,B。
连接查询🐍
内连接🕷
相当于查询A、B交集部分数据
如下图即是绿色的交集部分。
隐式内连接
SELECT 字段列表 FROM 表1,表2 WHERE 条件...;
代码实战
– 内连接演示
– 1.查询每一个员工的姓名,及关联的部门的名称(隐式内连接实现)
– 表结构:emp , dept
– 连接条件: emp.dept_id = dept.id
select emp.name , dept.name from emp , dept where emp.dept_id = dept.id order by emp.id ;
这里如果嫌字段列表名太长,可以选择起别名
-- 起别名,起别名之后只能使用别名去查询,因为DQL语句中先执行from语句--------------------
select e.name , d.name from emp e , dept d where e.dept_id = d.id ;
效果图
显式内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 ON 连接条件...;
实战代码
– 2.查询每一个员工的姓名,及关联的部门的名称(显式内连接实现)
– 表结构:emp , dept
– 连接条件: emp.dept_id = dept.id
select e.name , d.name from emp e inner join dept d on e.dept_id = d.id order by e.id;
同时inner可以选择忽略
select e.name , d.name from emp e join dept d on e.dept_id = d.id order by e.id;
效果图
外连接🕷
左外连接
查询左表所有数据,以及两张表交集部分数据。
即是集合A左半边和集合A与集合B的交集。
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件...;
实战代码
– 外连接演示--------------
– 1.查询emp表的所有数据,和对应的部门信息(左外连接)
– 表结构:emp,dept
– 连接方式:emp.dept_id = dept.id
select e.* , d.name from emp e left outer join dept d on e.dept_id = d.id ;
同样的 outer 可以选择忽略。
select e.* , d.name from emp e left join dept d on e.dept_id = d.id ;
效果图
右外连接
查询右表所有数据,以及两张表交集部分数据。
即是集合B右半边和集合A与集合B的交集。
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件...;
实战代码
– 2.查询dept表的所有数据,和对应的员工信息表(右外连接)
select d.* , e.* from emp e right outer join dept d on e.dept_id = d.id ;
效果图
自连接🕷
当前表与自身的连接查询,自连接必须使用表别名。
SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B ON 条件...;
实战代码
– 自连接
– 1.查询员工 及其 所属领导的名字
– 表结构 :emp
select a.name '员工' , b.name '领导' from emp a left join emp b on a.managerid = b.managerid ;
效果图
联合查询–union,union all🐍
对于联合查询,就是把多次查询的结果合并起来,形成一个新的查询结果集
SELECT 字段列表 FROM 表A ...
UNION[ALL]
SELECT 字段列表 FROM 表B ...;
实战代码
– union all , union
– 1.将薪资低于 5000 的员工 , 和 年龄大于 50 岁的员工全部查询出来。
select * from emp where salary < 5000
union
select * from emp where age > 50 ;
效果图
注意点🕷
union all 是直接将查询的两个表合并,而union 是将和并后的表进行去重。
对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
子查询🕷
1.概念 : SQL 语句中嵌套SELECT语句,称为嵌套语句,又称子查询
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
子查询外部的语句可以是INSERT / UPDATE / SELECT 的任何一个。
2.根据子查询结果不同,分为:
- 标量子查询(子查询结果为单个值)
- 列子查询(子查询结果为一列)
- 行子查询(子查询结果为一行)
- 表子查询(子查询结果为多行多列)
3.根据子查询位置,分为:WHERE 之后、FROM之后、SELECT之后。
标量子查询
- 子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询成为标量子查询
- 常见的操作符:= <> > >= < <=
实战代码
– 标量子查询
– 1.查询“销售部”的所有员工信息
– 查询出销售部的部门ID
select * from emp where dept_id = (select id from dept where name = '销售部') ;
效果图
列子查询
- 子查询返回的结果是一列(可以是多行),这种子查询称为列子查询。
- 常用的操作符:IN 、NOT IN、ANY、SOME、ALL
实战代码
– 列子查询
– 1.查询“销售部”和“市场部”的所有员工信息
– a.查询“销售部”和“市场部”的部门ID
– b.根据部门ID,查询员工信息
select * from emp where dept_id in (select id from dept where name = '销售部' or name = '市场部');
效果图
行子查询
- 子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。
- 常用操作符:= 、<> 、IN 、NOT IN
实战代码
– 行子查询
– 1.查询与 “张无忌” 的薪资及直属领导的员工信息
select * from emp where (salary,managerid)=( select salary ,managerid from emp where name = '张无忌');
效果图
表子查询
- 子查询返回的结果是多行多列, 这种子查询称为表子查询。
- 常用的操作符:IN 、
实战代码
– 表子查询
– 1. 查询与“宋远桥” , “鹿杖客” 的职位和薪资相同的员工信息
select * from emp where ( job , salary ) in (select job,salary from emp where name = '鹿杖客' or name = '宋远桥');
效果图
这篇文章就到此结束了,如果对你有所帮助就点个赞吧。