从 01 开始 从 01 开始
首页
  • 计算机简史
  • 数字电路
  • 计算机组成原理
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • MySQL
  • Git
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 输入法
  • 浏览器
  • 终端软件
  • 装机
  • 笔记类软件
  • Markdown
  • 微信
  • 各大平台
  • RSS
  • Office
  • 手机
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 教程简介
  • 英语学习方法论
  • 字母
  • 音标
  • 单词
  • 语法
  • 英语兔的相关视频
  • Larry 想做技术大佬的相关视频
  • 驾驶技能
  • 住房相关
  • 厨艺
  • 关于税
  • 理财
  • 睡眠
  • 皮肤
  • 口腔健康
  • 学会呼吸
  • 健身日志
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • 三国杀
  • 关于本站
  • 关于我
  • 网站动态
  • 友人帐
  • 打赏
  • 如何搭建一个博客
  • 关于邮件服务器
  • 本站的分享资料
  • 年度总结

    • 2022 年度总结
    • 2023 年度总结
  • 文章分类
  • 文章标签
  • 文章归档

PeterJXL

首页
  • 计算机简史
  • 数字电路
  • 计算机组成原理
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • MySQL
  • Git
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 输入法
  • 浏览器
  • 终端软件
  • 装机
  • 笔记类软件
  • Markdown
  • 微信
  • 各大平台
  • RSS
  • Office
  • 手机
  • 校招
  • 五险一金等
  • 职场规划
  • 关于离职
  • 杂谈
  • 教程简介
  • 英语学习方法论
  • 字母
  • 音标
  • 单词
  • 语法
  • 英语兔的相关视频
  • Larry 想做技术大佬的相关视频
  • 驾驶技能
  • 住房相关
  • 厨艺
  • 关于税
  • 理财
  • 睡眠
  • 皮肤
  • 口腔健康
  • 学会呼吸
  • 健身日志
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • 三国杀
  • 关于本站
  • 关于我
  • 网站动态
  • 友人帐
  • 打赏
  • 如何搭建一个博客
  • 关于邮件服务器
  • 本站的分享资料
  • 年度总结

    • 2022 年度总结
    • 2023 年度总结
  • 文章分类
  • 文章标签
  • 文章归档
  • 计算机历史

  • 数字电路

  • 计算机组成原理

  • 操作系统

  • Linux

  • 计算机网络

  • Git

  • 计算机小知识

  • MySQL

    • 教程概述
    • 数据的存储
    • 数据库的安装
    • 数据库的启停与连接
    • 数据库的管理
    • SQL概述
    • 表的管理
    • seletct基础
    • 运算符
    • 聚合查询
    • 排序
    • 数据的插入
    • 数据的删除
    • 数据的更新
    • 事务
    • 视图
    • 子查询
    • 函数
    • 谓词
    • CASE表达式
    • 集合运算
    • 联结-join
      • 什么是联结
      • INNER JOIN:内联结
      • OUTER JOIN:外联结
      • using
      • 3张表及以上的联结
      • CROSS JOIN:交叉联结
    • SQL入门小结
    • 更多数据库
    • MySQL的数据类型
    • 命令行的一些用法
    • 用户与权限管理
    • MySQL的权限管理
    • mysqldump
    • mysqladmin
    • Liquibase
    • 表注释与字段注释
    • 编码类型
  • 计算机基础
  • MySQL
2024-01-21
目录

联结-join

# 200.联结-join

联结(JOIN )就是将其他表中的列添加过来,进行“添加列”的集合运算。UNION 是以行(纵向)为单位进行操作,而联结则是以列(横向)为单位进行的。

联结大体上分为内联结和外联结两种。首先请大家牢牢掌握这两种联结的使用方法。

‍

# 什么是联结

前一节我们学习了 UNION 和 INTERSECT 等集合运算,这些集合运算的特征就是以行为单位进行操作。通俗地说,就是进行这些集合运算时,会导致记录行数的增减。使用 UNION 会增加记录行数,而使用 INTERSECT 或者 EXCEPT 会减少记录行数 。

但是这些运算不会导致列数的改变。作为集合运算对象的表的前提就是列数要一致。因此,运算结果不会导致列的增减。

‍

而联结(JOIN ) 运算,简单来说,就是将其他表中的列添加过来,进行“添加列”的运算。该操作通常用于无法从一张表中获取期望数据(列)的情况。截至目前,本书中出现的示例基本上都是从一张表中选取数据,但实际上,期望得到的数据往往会分散在不同的表之中。使用联结就可以从多张表(3 张以上的表也没关系)中选取数据了。

00124

SQL 的联结根据其用途可以分为很多种类,这里希望大家掌握的有两种,内联结和外联结。接下来,我们就以这两种联结为中心进行学习。

# INNER JOIN:内联结

内联结(INNER JOIN ) ,它是应用最广泛的联结运算。大家现在可以暂时忽略“内”这个字,之后会给大家详细说明。

‍

# 准备

本例中我们会使用 Product 表和 ShopProduct 表,我们再来回顾一下这两张表的内容:

Product (商品)表

product_id
(商品编号)
product_name
(商品名称)
product_type
(商品种类)
sale_price
(销售单价)
purchase_price
(进货单价)
regist_date
(登记日期)
0001 T 恤衫 衣服 1000 500 2009-09-20
0002 打孔器 办公用品 500 320 2009-09-11
0003 运动 T 恤 衣服 4000 2800
0004 菜刀 厨房用具 3000 2800 2009-09-20
0005 高压锅 厨房用具 6800 5000 2009-01-15
0006 叉子 厨房用具 500 2009-09-20
0007 擦菜板 厨房用具 880 790 2008-04-28
0008 圆珠笔 办公用品 100 2009-11-11

‍

ShopProduct (商店商品)表

shop_id
(商店编号)
shop_name
(商店名称)
product_id
(商品编号)
quantity
(数量)
000A 东京 0001 30
000A 东京 0002 50
000A 东京 0003 15
000B 名古屋 0002 30
000B 名古屋 0003 120
000B 名古屋 0004 20
000B 名古屋 0006 10
000B 名古屋 0007 40
000C 大阪 0003 20
000C 大阪 0004 50
000C 大阪 0006 90
000C 大阪 0007 70
000D 福冈 0001 100

‍

‍

两张表及其包含的列:

Product ShopProduct
商品编号 ○ ○
商品名称 ○
商品种类 ○
销售单价 ○
进货单价 ○
登记日期 ○
商店编号 ○
商店名称 ○
数量 ○

‍

# 开始使用

如上表所示,两张表中的列可以分为如下两类。

  • A:两张表中都包含的列 → 商品编号
  • B:只存在于一张表内的列 → 商品编号之外的列

所谓联结运算,一言以蔽之,就是“以A中的列作为桥梁,将B中满足同样条件的列汇集到同一结果之中”。

从 ShopProduct 表中的数据我们能够知道,东京店(000A )销售商品编号为 0001 、0002 和 0003 的商品,但这些商品的信息都保存在 Product 表中,ShopProduct表没有存储。

如果我们将两个表结合起来查询,就能查询出每个店铺销售的商品信息了:

SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price
  FROM ShopProduct AS SP INNER JOIN Product AS P 
    ON SP.product_id = P.product_id;


--结果:
+---------+-----------+------------+--------------+------------+
| shop_id | shop_name | product_id | product_name | sale_price |
+---------+-----------+------------+--------------+------------+
| 000A    | 东京      | 0001       | T恤衫        |       1000 |
| 000A    | 东京      | 0002       | 打孔器       |        500 |
| 000A    | 东京      | 0003       | 运动T恤      |       4000 |
| 000B    | 名古屋    | 0002       | 打孔器       |        500 |
| 000B    | 名古屋    | 0003       | 运动T恤      |       4000 |
| 000B    | 名古屋    | 0004       | 菜刀         |       3000 |
| 000B    | 名古屋    | 0006       | 叉子         |        500 |
| 000B    | 名古屋    | 0007       | 擦菜板       |        880 |
| 000C    | 大阪      | 0003       | 运动T恤      |       4000 |
| 000C    | 大阪      | 0004       | 菜刀         |       3000 |
| 000C    | 大阪      | 0006       | 叉子         |        500 |
| 000C    | 大阪      | 0007       | 擦菜板       |        880 |
| 000D    | 福冈      | 0001       | T恤衫        |       1000 |
+---------+-----------+------------+--------------+------------+
13 rows in set (0.00 sec)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

‍

‍

# 内联结要点① FROM 子句

FROM 子句:之前的 FROM 子句中只有一张表,而这次我们同时使用了 ShopProduct 和 Product 两张表。

FROM ShopProduct AS SP INNER JOIN Product AS P
1

使用关键字 INNER JOIN 就可以将两张表联结在一起了。SP 和 P 分别是这两张表的别名,但别名并不是必需的。在 SELECT 子句中直接使用 ShopProduct 和 product_id 这样的表的原名也没有关系,但由于表名太长会影响 SQL 语句的可读性,因此还是希望大家能够习惯使用别名 。

‍

‍

# 内联结要点② ON 子句

第二点要注意的是 ON 后面的联结条件。

ON SP.product_id = P.product_id
1

我们可以在 ON 之后指定两张表联结所使用的列(联结键 ),本例中使用的是商品编号(product_id )。也就是说,ON 是专门用来指定联结条件的,它能起到与 WHERE 相同的作用。需要指定多个键时,同样可以使用 AND 、OR 。

在进行内联结时 ON 子句是必不可少的(如果没有 ON 会发生错误),并且 ON 必须书写在 FROM 和 WHERE 之间。

‍

‍

# 内联结要点③ SELECT 子句

第三点要注意的是,在 SELECT 子句中指定的列。

SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price
1

在 SELECT 子句中,像 SP.shop_id 和 P.sale_price 这样使用“< 表的别名 >.< 列名 >”的形式来指定列。和使用一张表时不同,由于多表联结时,某个列到底属于哪张表比较容易混乱,因此采用了这样的防范措施。从语法上来说,只有那些同时存在于两张表中的列(这里是 product_id )必须使用这样的书写方式,其他的列像 shop_id 这样直接书写列名也不会发生错误。

但是就像前面说的那样,为了避免混乱,还是希望大家能够在使用联结时按照“< 表的别名 >.< 列名 >”的格式来书写 SELECT 子句中全部的列。

‍

‍

‍

# 内联结和 WHERE 子句结合使用

如果并不想了解所有商店的情况,例如只想知道东京店(000A )的信息时,可以像之前学习的那样在 WHERE 子句中添加条件:

SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price
  FROM ShopProduct AS SP INNER JOIN Product AS P 
    ON SP.product_id = P.product_id
 WHERE SP.shop_id = '000A';
1
2
3
4

像这样使用联结运算将满足相同规则的表联结起来时,WHERE 、GROUP BY 、HAVING 、ORDER BY 等工具都可以正常使用。我们可以将联结之后的结果想象为新创建出来的一张表。当然,这张“表”只在 SELECT 语句执行期间存在,SELECT 语句执行之后就会消失。

‍

‍

# OUTER JOIN:外联结

外联结也是通过 ON 子句的联结键将两张表进行联结,并从两张表中同时选取相应的列的。基本的使用方法并没有什么不同,只是结果却有所不同。

直接来看看结果吧:

SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price
  FROM ShopProduct AS SP RIGHT OUTER JOIN Product AS P 
    ON SP.product_id = P.product_id;

-- 结果:
+---------+-----------+------------+--------------+------------+
| shop_id | shop_name | product_id | product_name | sale_price |
+---------+-----------+------------+--------------+------------+
| 000D    | 福冈      | 0001       | T恤衫        |       1000 |
| 000A    | 东京      | 0001       | T恤衫        |       1000 |
| 000B    | 名古屋    | 0002       | 打孔器       |        500 |
| 000A    | 东京      | 0002       | 打孔器       |        500 |
| 000C    | 大阪      | 0003       | 运动T恤      |       4000 |
| 000B    | 名古屋    | 0003       | 运动T恤      |       4000 |
| 000A    | 东京      | 0003       | 运动T恤      |       4000 |
| 000C    | 大阪      | 0004       | 菜刀         |       3000 |
| 000B    | 名古屋    | 0004       | 菜刀         |       3000 |
| 000C    | 大阪      | 0006       | 叉子         |        500 |
| 000B    | 名古屋    | 0006       | 叉子         |        500 |
| 000C    | 大阪      | 0007       | 擦菜板       |        880 |
| 000B    | 名古屋    | 0007       | 擦菜板       |        880 |
| NULL    | NULL      | NULL       | 高压锅       |       6800 |
| NULL    | NULL      | NULL       | 圆珠笔       |        100 |
+---------+-----------+------------+--------------+------------+
15 rows in set (0.00 sec)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

‍

# 外联结要点① 选取出单张表中全部的信息

与内联结的结果相比,不同点显而易见,那就是结果的行数不一样。内联结的结果中有 13 条记录,而外联结的结果中有 15 条记录,增加的 2 条记录到底是什么呢?

这正是外联结的关键点。多出的 2 条记录是高压锅和圆珠笔,这 2 条记录在 ShopProduct 表中并不存在,也就是说,这 2 种商品在任何商店中都没有销售。由于内联结只能选取出同时存在于两张表中的数据,因此只在 Product 表中存在的 2 种商品并没有出现在结果之中。

相反,对于外联结来说,只要数据存在于某一张表当中,就能够读取出来。在实际的业务中,例如想要生成固定行数的单据时,就需要使用外联结。如果使用内联结的话,根据 SELECT 语句执行时商店库存状况的不同,结果的行数也会发生改变,生成的单据的版式也会受到影响,而使用外联结能够得到固定行数的结果。

虽说如此,那些表中不存在的信息我们还是无法得到,结果中高压锅和圆珠笔的商店编号和商店名称都是 NULL (具体信息大家都不知道,真是无可奈何)。外联结名称的由来也跟 NULL 有关,即“结果中包含原表中不存在(在原表之外)的信息”。相反,只包含表内信息的联结也就被称为内联结了。

‍

# 外联结要点② 每张表都是主表吗?

外联结还有一点非常重要,那就是要把哪张表作为主表。最终的结果中会包含主表内所有的数据。指定主表的关键字是 LEFT 和 RIGHT 。顾名思义,使用 LEFT 时 FROM 子句中写在左侧的表是主表,使用 RIGHT 时右侧的表是主表。

大家可能会犹豫到底应该使用 LEFT 还是 RIGHT ,其实它们的功能没有任何区别,使用哪一个都可以。

‍

‍

# using

sql/92标准可以使用using关键字来简化连接查询,但是只是在查询满足下面两个条件时,才能使用using关键字进行简化。

  1. 查询必须是等值连接(用=号)。
  2. 等值连接中的列必须具有相同的名称和数据类型。

例如:

SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name, P.sale_price
  FROM ShopProduct AS SP INNER JOIN Product AS P
  USING (product_id)
  WHERE SP.shop_id = '000A';
1
2
3
4

‍

# 3张表及以上的联结

通常联结只涉及 2 张表,但有时也会出现必须同时联结 3 张以上的表的情况。原则上联结表的数量并没有限制,语法上也没什么不同,只需添加 join 和 on即可,例如:


select *
from a 
inner join b on a.id = b.id
inner join c on a.id = c.id
1
2
3
4
5

‍

‍

# CROSS JOIN:交叉联结

交叉联结(CROSS JOIN),在实际业务中并不会使用,为什么还要在这里进行介绍呢?这是因为交叉联结是所有联结运算的基础。

交叉联结本身非常简单,但是其结果有点麻烦。下面我们就试着将 Product 表和 ShopProduct 表进行交叉联结:

SELECT SP.shop_id, SP.shop_name, SP.product_id, P.product_name
FROM ShopProduct AS SP CROSS JOIN Product AS P; 


-- 结果:
+---------+-----------+------------+--------------+
| shop_id | shop_name | product_id | product_name |
+---------+-----------+------------+--------------+
| 000A    | 东京      | 0001       | 圆珠笔       |
| 000A    | 东京      | 0001       | 擦菜板       |
| 000A    | 东京      | 0001       | 叉子         |
| 000A    | 东京      | 0001       | 高压锅       |
| 000A    | 东京      | 0001       | 菜刀         |
| 000A    | 东京      | 0001       | 运动T恤      |
| 000A    | 东京      | 0001       | 打孔器       |
| 000A    | 东京      | 0001       | T恤衫        |
| 000A    | 东京      | 0002       | 圆珠笔       |
| 000A    | 东京      | 0002       | 擦菜板       |
| 000A    | 东京      | 0002       | 叉子         |
| 000A    | 东京      | 0002       | 高压锅       |
| 000A    | 东京      | 0002       | 菜刀         |
| 000A    | 东京      | 0002       | 运动T恤      |
| 000A    | 东京      | 0002       | 打孔器       |
| 000A    | 东京      | 0002       | T恤衫        |
| 000A    | 东京      | 0003       | 圆珠笔       |
| 000A    | 东京      | 0003       | 擦菜板       |
| 000A    | 东京      | 0003       | 叉子         |
| 000A    | 东京      | 0003       | 高压锅       |
| 000A    | 东京      | 0003       | 菜刀         |
| 000A    | 东京      | 0003       | 运动T恤      |
| 000A    | 东京      | 0003       | 打孔器       |
| 000A    | 东京      | 0003       | T恤衫        |
| 000B    | 名古屋    | 0002       | 圆珠笔       |
| 000B    | 名古屋    | 0002       | 擦菜板       |
| 000B    | 名古屋    | 0002       | 叉子         |
| 000B    | 名古屋    | 0002       | 高压锅       |
| 000B    | 名古屋    | 0002       | 菜刀         |
| 000B    | 名古屋    | 0002       | 运动T恤      |
| 000B    | 名古屋    | 0002       | 打孔器       |
| 000B    | 名古屋    | 0002       | T恤衫        |
| 000B    | 名古屋    | 0003       | 圆珠笔       |
| 000B    | 名古屋    | 0003       | 擦菜板       |
| 000B    | 名古屋    | 0003       | 叉子         |
| 000B    | 名古屋    | 0003       | 高压锅       |
| 000B    | 名古屋    | 0003       | 菜刀         |
| 000B    | 名古屋    | 0003       | 运动T恤      |
| 000B    | 名古屋    | 0003       | 打孔器       |
| 000B    | 名古屋    | 0003       | T恤衫        |
| 000B    | 名古屋    | 0004       | 圆珠笔       |
| 000B    | 名古屋    | 0004       | 擦菜板       |
| 000B    | 名古屋    | 0004       | 叉子         |
| 000B    | 名古屋    | 0004       | 高压锅       |
| 000B    | 名古屋    | 0004       | 菜刀         |
| 000B    | 名古屋    | 0004       | 运动T恤      |
| 000B    | 名古屋    | 0004       | 打孔器       |
| 000B    | 名古屋    | 0004       | T恤衫        |
| 000B    | 名古屋    | 0006       | 圆珠笔       |
| 000B    | 名古屋    | 0006       | 擦菜板       |
| 000B    | 名古屋    | 0006       | 叉子         |
| 000B    | 名古屋    | 0006       | 高压锅       |
| 000B    | 名古屋    | 0006       | 菜刀         |
| 000B    | 名古屋    | 0006       | 运动T恤      |
| 000B    | 名古屋    | 0006       | 打孔器       |
| 000B    | 名古屋    | 0006       | T恤衫        |
| 000B    | 名古屋    | 0007       | 圆珠笔       |
| 000B    | 名古屋    | 0007       | 擦菜板       |
| 000B    | 名古屋    | 0007       | 叉子         |
| 000B    | 名古屋    | 0007       | 高压锅       |
| 000B    | 名古屋    | 0007       | 菜刀         |
| 000B    | 名古屋    | 0007       | 运动T恤      |
| 000B    | 名古屋    | 0007       | 打孔器       |
| 000B    | 名古屋    | 0007       | T恤衫        |
| 000C    | 大阪      | 0003       | 圆珠笔       |
| 000C    | 大阪      | 0003       | 擦菜板       |
| 000C    | 大阪      | 0003       | 叉子         |
| 000C    | 大阪      | 0003       | 高压锅       |
| 000C    | 大阪      | 0003       | 菜刀         |
| 000C    | 大阪      | 0003       | 运动T恤      |
| 000C    | 大阪      | 0003       | 打孔器       |
| 000C    | 大阪      | 0003       | T恤衫        |
| 000C    | 大阪      | 0004       | 圆珠笔       |
| 000C    | 大阪      | 0004       | 擦菜板       |
| 000C    | 大阪      | 0004       | 叉子         |
| 000C    | 大阪      | 0004       | 高压锅       |
| 000C    | 大阪      | 0004       | 菜刀         |
| 000C    | 大阪      | 0004       | 运动T恤      |
| 000C    | 大阪      | 0004       | 打孔器       |
| 000C    | 大阪      | 0004       | T恤衫        |
| 000C    | 大阪      | 0006       | 圆珠笔       |
| 000C    | 大阪      | 0006       | 擦菜板       |
| 000C    | 大阪      | 0006       | 叉子         |
| 000C    | 大阪      | 0006       | 高压锅       |
| 000C    | 大阪      | 0006       | 菜刀         |
| 000C    | 大阪      | 0006       | 运动T恤      |
| 000C    | 大阪      | 0006       | 打孔器       |
| 000C    | 大阪      | 0006       | T恤衫        |
| 000C    | 大阪      | 0007       | 圆珠笔       |
| 000C    | 大阪      | 0007       | 擦菜板       |
| 000C    | 大阪      | 0007       | 叉子         |
| 000C    | 大阪      | 0007       | 高压锅       |
| 000C    | 大阪      | 0007       | 菜刀         |
| 000C    | 大阪      | 0007       | 运动T恤      |
| 000C    | 大阪      | 0007       | 打孔器       |
| 000C    | 大阪      | 0007       | T恤衫        |
| 000D    | 福冈      | 0001       | 圆珠笔       |
| 000D    | 福冈      | 0001       | 擦菜板       |
| 000D    | 福冈      | 0001       | 叉子         |
| 000D    | 福冈      | 0001       | 高压锅       |
| 000D    | 福冈      | 0001       | 菜刀         |
| 000D    | 福冈      | 0001       | 运动T恤      |
| 000D    | 福冈      | 0001       | 打孔器       |
| 000D    | 福冈      | 0001       | T恤衫        |
+---------+-----------+------------+--------------+
104 rows in set (0.00 sec)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

‍

‍

‍

为什么有100多行结果呢?这是因为交叉联结是对两张表中的全部记录进行交叉组合,因此结果中的记录数通常是两张表中行数的乘积。

本例中,因为 ShopProduct 表存在 13 条记录,Product 表存在 8 条记录,所以结果中就包含了 13 × 8 = 104 条记录(其实就是笛卡尔积),这也就是为什么该联结无需使用on进行条件指定键

内联结是交叉联结的一部分,“内”也可以理解为“包含在交叉联结结果中的部分”。相反,外联结的“外”可以理解为“交叉联结结果之外的部分”。

可以理解为,在内/外联结的时候,先通过笛卡尔积形成一个结果集,然后再根据on条件进行筛选。

‍

交叉联结没有应用到实际业务之中的原因有两个。一是其结果没有实用价值,二是由于其结果行数太多,需要花费大量的运算时间和高性能设备的支持。

‍

‍

上次更新: 2024/5/30 15:25:05
集合运算
SQL入门小结

← 集合运算 SQL入门小结→

Theme by Vdoing | Copyright © 2022-2024 | 粤 ICP 备 2022067627 号-1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式