MySQL之多表查询

1. 前言

  • 多表查询,也称为关联查询.指两个或两个以上的表一起完成查询操作.
  • 前提条件 : 这些一起查询的表之间是有关系的(一对一/一对多).他们之间一定是有关联字段,这个关联字段可能建立了外键,也可能没有建立外键.

2. 笛卡尔积现象(交叉连接)

(1).例 :

如果我们在两个表中未进行条件关联,直接查找,可能会出现笛卡尔积现象.即第一张表的一个数据需要跟第二张表的所有数据匹配.又称交叉连接.

  • 图中2889条数据=第一张表的记录数X第二张表的记录数.
  • CROSS JOIN的作用就是可以把任意表进行连接,即使这两张表不相关.
  • 为了避免出现笛卡尔积现象,我们可以在WHERE子句中加入有效的条件.

3. 带有连接条件的多表查询

例 :

  • 从第一张表的第一条记录开始,与第二章表的所有记录进行条件关联,剩下的是满足关联条件的记录. 只剩下106条记录.因为employees表中第一条记录的departmentid字段为null.
  • FROM子句中,可以给表起别名.一旦起了别名,后续WHERE子句中,就不能使用以前的表名了.相当于表的别名对原先的表名进行了覆盖.但字段的别名不会对原字段进行覆盖.

4. 多表查询的分类

  • 等值连接与非等值连接
  • 自连接与非自连接
  • 内连接与外连接

5. 等值连接与非等值连接

(1).等值连接 :

上述例就是等值连接.因为连接条件是=运算符.

(2). 非等值连接 :

自然而然,连接条件不是=运算符的,即是非等值连接.比如 :

  • 当查询的字段是两个表中的共有字段时,需要指定是哪个表中的字段.不然会报错.
  • 对于数据库中表记录的查询和变更,只要涉及多个表,都需要在列名前加表的别名进行限定(如d.locationid).

6. 自连接与非自连接

(1). 自连接

例 :

  • 自连接顾名思义,自己的表与自己连接查询.
  • emp与mana本质上是一张表(物理磁盘上只有一张表),只是用取别名的方式在逻辑上虚拟成两个表代表不同的意义,然后两个表进行内连接,外连接.

(2) 非自连接

上述例均为非自连接.

7. 内连接与外连接

(1). 内连接 : (数学中的交集)

上述我们涉及到的全部例子均是内连接.

合并具有同一列的两个以上的行,结果集中不包含一个表与另一个表不匹配的行.

格式为 :

SELECT 字段列表

INNER可省略.

FROM A表 JOIN B表

ON 关联条件

WHERE 等其他子句.

例 :

只能查询到满足关联条件的记录,不能查询到不满足条件的记录.

还可以多个表内连接.

(2). 外连接

  • 外连接分为 : 左外连接,右外连接,满外连接.
  • 左外连接(LEFT OUTER JOIN / LEFT JOIN) : 结果集中不仅包含了两个表中满足连接条件的记录,还包含了左表中不满足连接条件的记录.
  • 右外连接(RIGHT OUTER JOIN / RIGHT JOIN) : 结果集中不仅包含了两个表中满足连接条件的记录,还包含了右表中不满足连接条件的记录.
  • 满外连接 : 结果集中不仅包含了两个表中满足条件的记录,还包含了左表中不满足条件的记录+右表中不满足条件的记录.

8. 左外连接与右外连接

(1). 左外连接

例 :

可以看到有107条记录,而上述内连接的情况下只有106条记录.可知左外连接包含了左表不满足条件的记录.

(2). 右表连接

右表连接与左表连接类似.

格式 :

SELECT 查询字段

FROM A表

RIGHT JOIN B表

ON 连接条件

WHERE 其他子句.

9. 满外连接与UNION关键字

  • SQL99是支持满外连接的.即使用FULL JOIN/FULL OUTER JOIN来实现
  • 但MySQL并不支持这种写法.但可以使用LEFT JOIN UNION RIGHT JOIN代替.

10. UNION的使用

(1). 合并查询结果 : 利用UNION关键字,可以给出多条SELECT语句,并将他们的结果组合成单个结果集.合并时,两个表对应的列数和数据类型必须相同.并且相互对应.各个SELECT语句间使用UNION/UNION ALL关键字分隔.

(2). UNION操作符

返回两个查询的结果集的并集,并去重复记录.

(3). UNION ALL操作符

返回两个查询的结果集的并集,但并不去重.

注意 : 执行UNION ALL语句时所需要的资源比UNION语句少.如果明知合并数据候的结果集不存在重复数据,或不需要去重,则尽量使用UNION ALL语句,以提高查询效率.

(4). 例 : UNION ALL实现连接 : 对应下表 左中 UNION ALL 右上 ---> 左下

sql 复制代码
SELECT employee_id,last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL
UNION ALL #没有去重操作,效率高
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments dON e.`department_id` = d.`department_id`;

11. 七种SQL JOINS的实现

如图 :

  • 左上 : 左外连接 LEFT JOIN
  • 左中 : 左外连接+WHERE过滤匹配的行
  • 左下 : 左外连接+WHERE过滤匹配的行 UNION ALL 右外连接 / 右外连接+WHERE过滤匹配的行 UNION ALL 左外连接
  • 中上 : 内连接 仅有匹配的行
  • 右下 : 左外连接+WHERE过滤匹配的行 UNION ALL 右外连接+WHERE过滤匹配的行
  • 右上 : 右外连接 RIGHT JOIN
  • 右中 : 右外连接+WHERE过滤匹配的行
相关推荐
喝醉的小喵1 分钟前
【mysql】并发 Insert 的死锁问题 第二弹
数据库·后端·mysql·死锁
付出不多41 分钟前
Linux——mysql主从复制与读写分离
数据库·mysql
源远流长jerry1 小时前
MySQL的缓存策略
数据库·mysql·缓存
初次见面我叫泰隆2 小时前
MySQL——3、数据类型
数据库·mysql
weixin_472339463 小时前
MySQL MCP 使用案例
数据库·mysql
lqlj22334 小时前
Spark SQL 读取 CSV 文件,并将数据写入 MySQL 数据库
数据库·sql·spark
遗憾皆是温柔5 小时前
MyBatis—动态 SQL
java·数据库·ide·sql·mybatis
未来之窗软件服务5 小时前
Cacti 未经身份验证SQL注入漏洞
android·数据库·sql·服务器安全
fengye2071615 小时前
在MYSQL中导入cookbook.sql文件
数据库·mysql·adb
拓端研究室TRL5 小时前
Python与MySQL网站排名数据分析及多层感知机MLP、机器学习优化策略和地理可视化应用|附AI智能体数据代码
人工智能·python·mysql·机器学习·数据分析