【MySQL数据库 | 第12篇】多表查询

在这里插入图片描述

🥝多表关系

概述

在项目开发中,进行数据表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间互相关联,所以各个表结构之间也存在着各种联系,基本上分为三种:
1.一对多(多对一)
2.多对多
3.一对一

🍉一对多(多对一)

例子:
在这里插入图片描述

🍉多对多

例子:
在这里插入图片描述
在这里插入图片描述

🍉一对一

例子:
在这里插入图片描述

🥝多表查询

多表查询时需要去掉多余的笛卡尔积【使用WHERE条件句即可】

什么是笛卡尔积

👏示例数据表

在这里插入图片描述

🔜 笛卡尔积效果演示

【说明】:运行了标亮的Sql语句后,发现显示的结果是所有人都选了所有课程(数据没截完,太多了),显然,这不是我们想要的设计结果
【使用WHERE条件句即可消除多余的笛卡尔积数据】
Sql语句【未使用WHERE条件句,产生了很多多余的笛卡尔积】:

SELECT * FROM course,student;  

在这里插入图片描述
Sql语句【使用了WHERE条件句,消除了多余的笛卡尔积,得到了正确的结果】:

SELECT * FROM course,student WHERE  course.id = student.course_id;    

在这里插入图片描述


🧾多表查询分类

在这里插入图片描述

🍋‍🟩连接查询 - 内连接【内连接查询码的是两张表的交集部分】

隐式内连接🍉

语法

SELECT 字段列表 FROM 表1,表2 WHERE 条件…

举例:只显示该选课学生的名字和所选课程的名字【给course表起了别名a,student表起了别名b】

SELECT a.name,b.name FROM course a,student b WHERE a.id = b.course_id;

显示内连接🍉

语法

SELECT 字段列表 FROM 表1 [ INNER ] JOIN 表2 ON 连接条件…
中括号[ ] 中的内容代表可以省略

举例:【与上面一样】

SELECT a.name,b.name FROM course a INNER join student b ON a.id = b.course_id;

上面的隐式内连接和显示内连接的结果均一样,如下图:
在这里插入图片描述

两种连接方式的区别:1.表的连接形式不同 2.连接条件的形式不同

🍋‍🟩连接查询 - 外连接

温馨提示:外连接查询的结果为主表中所有的记录。如果从表中有和它匹配的,则显示匹配的值,这部分相当于内连接查询出来的结果;如果从表中没有和它匹配的,则显示null。
即:外连接查询的结果 = 内连接的结果 + 主表中有的而内连接结果中没有的记录

左外连接🍉

语法

SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件…
1.相当于查询表1(左表)的所有数据,包含 表1和表2交集部分的数据
2.中括号[ ] 中的内容代表可以省略

示例语句:

SELECT a.name,b.name FROM course a LEFT OUTER join student b ON a.id = b.course_id;

右外连接🍉

语法

SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件…
1.相当于查询表2(右表)的所有数据,包含 表1和表2交集部分的数据
2.中括号[ ] 中的内容代表可以省略

示例语句:

SELECT a.name,b.name FROM course a RIGHT OUTER join student b ON a.id = b.course_id;

🍋‍🟩连接查询 - 自连接(把一张表看成两张表来操作)

语法🍉

SELECT 字段列表 FROM 表A 别名A JOIN 表A 别名B 条件…
自连接查询,可以是内连接查询,也可以是外连接查询
示例代码:【要查询该员工的名字和其领导的名字,而员工信息和领导信息都在同一张表里】

SELECT a.name '员工', b.name '领导' FROM emp a LEFT JOIN emp b ON a.managerid = b.id;

🍋‍🟩联合查询

对于union查询, 就是把多次查询的结果合并起来, 形成一个新的查询结果

语法🍉

SELECT 字段列表 FROM 表A …
UNION [ ALL ]
SELECT 字段列表 FROM 表B …

特别注意:

  1. UNION ALL 会将全部数据直接合并到一起(可能存在重复),而 UNION 会对合并后的数据去重
  2. 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致
案例:用一条Sql语句将薪资低于5000的员工和年龄大于50岁的员工全部查询出来(两个条件独立)
SELECT * FROM emp WHERE salary < 5000
UNION ALL 
SELECT * FROM emp WHERE age > 50;

运行结果:
在这里插入图片描述
【直接把两个语句的查询结果合并到一起来显示了,但是这样出现了重复–>id为11的鹿杖客两个条件都满足,出现了两次,所以我们可以把ALL去掉,这样就不会出现重复了,自动去重】

🍋‍🟩子查询

概念:SQL语句中嵌套SELECT语句,成为嵌套查询,又称为子查询

语法🍉

SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2)

说明:子查询外部的语句可以是INSERT/UPDATE/DELETE/SELECT中的任意一个

子查询类别🧾

1.根据子查询结果的不同,分为:

子查询列别子查询结果
标量子查询子查询结果为单个值
列子查询子查询结果为一列
行子查询子查询结果为一行
表子查询子查询结果为多行多列

2.根据子查询位置,分为:WHERE之后FROM之前SELECT之后

🍋标量子查询 (子查询结果为单个值)

概览:子查询返回的结果是单个值(数字、字符串、日期等),常见的操作符:= 、<> 、>、>=、<、<=

示例 — 查询 “销售部” 的所有员工信息

可拆解为两步:
a.查询 “销售部” 的部门ID
b.根据销售部的部门ID,查询员工信息

合并,使用标量子查询,SQL语句:

SELECT * FROM emp WHERE dept_id = (SELECT id FROM dept WHERE name = '销售部');
🍋列子查询 (子查询结果为一列)

在这里插入图片描述
说明:IN是确定的集合,而ANY/SOME可以是区间和模糊范围

案例1 — 查询"销售部"和"市场部"的所有员工信息
SELECT * FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE name = '销售部' OR name = '市场部');
案例2 — 查询比 财务部 所有人的工资都要高的员工信息

分解步骤:
a.查询财务部所有的人员工资
b.查询 比所有财务部的人员工资都要高的人员信息

SELECT * FROM emp WHERE salary > ALL( SELECT salary FROM emp 
WHERE id = (SELECT id FROM dept WHERE name = '财务部') )
🍋行子查询 (子查询结果为一行)

常用的操作符:= 、<> 、IN 、NOT IN

案例 — 查询与 林七夜的薪资 及 直属领导 相同的员工信息
SELECT * FROM emp WHERE (salary,managerid) = (SELECT salary,managerid FROM emp WHERE name = '林七夜');
🍋表子查询 (子查询结果为多行多列)

常用操作符:IN

案例 — 查询 与 林七夜 或 微微 的职位和薪资相同的员工信息
SELECT * FROM emp WHERE (position,salary) IN (SELECT position,salary 
FROM emp WHERE name = '林七夜' OR name = '微微');

如果我的内容对你有帮助,请 点赞 评论 收藏 。创作不易,大家的支持就是我坚持下去的动力!
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

青衫码上行

你的鼓励将是我最大的动力!

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

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

打赏作者

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

抵扣说明:

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

余额充值