MySQL 之 join 详解

说明:本学习笔记参考了
慕课网《MySQL开发技巧(一)》视频教程,讲师 sqlercn 。
MySQL开发技巧(一)丨章节
http://www.imooc.com/learn/398

SQL语言介绍
正确使用 SQL 语句是非常重要的。
1、增加数据库的处理效率,减少应用相应时间;
2、减少数据库服务器负载,增加服务器稳定性;
3、减少服务器间通讯的网络流量。

join 语句的类型
1、内连接
2、全外连接
3、左外连接
4、右外连接
5、交叉连接

执行环境:

CREATE TABLE user1(
  id INT PRIMARY KEY AUTO_INCREMENT ,
  user_name VARCHAR(100),
  over VARCHAR(100)
);

INSERT user1 VALUES(NULL,"唐僧","唐僧成佛了");
INSERT user1 VALUES(NULL,"猪八戒","猪八戒成佛了");
INSERT user1 VALUES(NULL,"孙悟空","孙悟空成佛了");
INSERT user1 VALUES(NULL,"沙僧","沙僧成佛了");

CREATE TABLE user2(
  id INT PRIMARY KEY AUTO_INCREMENT ,
  user_name VARCHAR(100),
  over VARCHAR(100)
);

INSERT user2 VALUES(NULL,"孙悟空","成佛");
INSERT user2 VALUES(NULL,"蜘蛛精","被降服");
INSERT user2 VALUES(NULL,"牛魔王","被降服");
INSERT user2 VALUES(NULL,"铁扇公主","被降服");
INSERT user2 VALUES(NULL,"女儿国国王","被降服");

1、内连接

SELECT
  a.id,
  a.user_name,
  a.over,
  b.id,
  b.user_name,
  b.over
FROM user1 a
  INNER JOIN user2 b
    ON a.user_name = b.user_name

查询结果:
这里写图片描述

2、左外连接

SELECT
  a.id,
  a.user_name,
  a.over,
  b.id,
  b.user_name,
  b.over
FROM user1 a
  LEFT JOIN user2 b
    ON a.user_name = b.user_name

查询结果:
这里写图片描述
我们可以看到,作为左表的 user1 表中的记录全部显示,右表中与左表不能匹配的字段值显示为空。

注意:利用左外连接,我们还可以查询出只在左表中出现的数据的集合,只需要再加一个 where 子句就可以了。

SELECT
  a.id,
  a.user_name,
  a.over,
  b.id,
  b.user_name,
  b.over
FROM user1 a
  LEFT JOIN user2 b
    ON a.user_name = b.user_name
    WHERE b.user_name IS NULL;

3、右外连接

SELECT
  a.id,
  a.user_name,
  a.over,
  b.id,
  b.user_name,
  b.over
FROM user1 a
  RIGHT JOIN user2 b
    ON a.user_name = b.user_name

查询结果:
这里写图片描述
分析类似左外连接。右边的表 user2 中的记录全部显示。

同样地,在右外连接中也可以查询出只在右外连接中有的记录。

SELECT
  a.id,
  a.user_name,
  a.over,
  b.id,
  b.user_name,
  b.over
FROM user1 a
  RIGHT JOIN user2 b
    ON a.user_name = b.user_name
    WHERE a.user_name IS NULL;

这里写图片描述
4、全外连接
MySQL 并不支持全外连接。但是我们可以使用 union all 语句实现全连接。

SELECT   a.id,  a.user_name,  a.over,  b.id,  b.user_name,  b.over 
FROM user1 a
  LEFT JOIN user2 b
    ON a.user_name = b.user_name
UNION ALL
SELECT   a.id,  a.user_name,  a.over,  b.id,  b.user_name,  b.over 
FROM user1 a
  RIGHT JOIN user2 b
    ON a.user_name = b.user_name

查询结果:
这里写图片描述

类似地,全连接还可以查询出只存在于两个集合中的元素的集合,也就是把它们的公共数据排除掉。

SELECT   a.id,  a.user_name,  a.over,  b.id,  b.user_name,  b.over 
FROM user1 a
  LEFT JOIN user2 b
    ON a.user_name = b.user_name WHERE b.user_name IS NULL
UNION ALL
SELECT   a.id,  a.user_name,  a.over,  b.id,  b.user_name,  b.over 
FROM user1 a
  RIGHT JOIN user2 b
    ON a.user_name = b.user_name WHERE a.user_name IS NULL

查询结果集:
这里写图片描述

5、交叉连接

SELECT
  a.id,
  a.user_name,
  a.over,
  b.id,
  b.user_name,
  b.over
FROM user1 a,
  user2 b

显示结果:
这里写图片描述
还可以这样写:

SELECT
  a.id,
  a.user_name,
  a.over,
  b.id,
  b.user_name,
  b.over
FROM user1 a CROSS JOIN
  user2 b

上面回顾了关于 MySQL 表连接的基本知识,下面开始介绍关于 join 的使用技巧。

1、使用 join 更新表

我们的需求是:把同时存在于师徒四人表和悟空兄弟表中的记录的人在师徒四人表中的 over 字段修改为“齐天大圣孙行者”。

UPDATE user1 a 
INNER JOIN ( SELECT b.user_name 
             FROM user1 a INNER JOIN user2 b 
             ON a.user_name = b.user_name) b
ON a.user_name = b.user_name
             SET a.over = '齐天大圣孙行者';

分析:我们使用下面的查询语句,将会得到:

SELECT * FROM user1 a 
INNER JOIN ( SELECT b.user_name 
             FROM user1 a INNER JOIN user2 b 
             ON a.user_name = b.user_name) b
ON a.user_name = b.user_name

这里写图片描述
关键:如果我们去修改悟空兄弟表中的 over 字段,就会报错。
这里写图片描述

2、使用 join 优化子查询

需求1:我们想查询 user1 表中 user_name 字段在 user2 表中有的。
我们最最直接的想法:

SELECT a.id,a.user_name,a.over
FROM user1 a 
WHERE a.user_name IN(SELECT b.user_name FROM user2 b);

但是这样做效率并不高,为此,我们可以这样优化:

SELECT a.id,a.user_name,a.over FROM user1 a
 JOIN user2 b ON a.user_name=b.user_name

注意: join 如果什么都不写,默认是内连接。

查询得到的结果集是一样的。

注意:如果 user1 这张表与 user2 这张表是一对多关系的话,要注意去重。可以简单思考一下为什么会有重复。

测试语句:

INSERT INTO user2 VALUES(NULL,'孙悟空','成为了齐天大圣');

最佳实践:

SELECT DISTINCT a.id,a.user_name,a.over FROM user1 a
 JOIN user2 b ON a.user_name=b.user_name

需求2:我想查询出 user1 里面 id、user_name ,user2 里面的 over 字段,一定要 user_name 匹配才行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MySQL 中的 hash join 是一种连接两个表的方法,它通过将其中一个表的数据哈希到内存中的哈希表来实现。另一个表的数据在哈希表上进行匹配,从而得到符合条件的行。 这种方法适用于其中一个表的数据量较小的情况。因为哈希表的查询速度很快,所以这种方法效率高。但是,如果其中一个表的数据量很大,则需要将整个表加载到内存中,这可能会导致内存不足。 在 MySQL 中,使用 INNER JOIN、LEFT JOIN 或 RIGHT JOIN 关键字可以实现 hash join 操作。 ### 回答2: MySQL的hashJoin是一种关联查询的算法,用于将两个表中的数据进行关联。它通过计算每个表的关联列的哈希值,将相同哈希值的记录分配到同一个哈希桶中,然后对每个哈希桶进行内存中的关联操作。 首先,hashJoin需要将两个要关联的表按照关联列进行哈希分区。然后,对于第一个表的每个分区,将其哈希列值与第二个表进行匹配。如果哈希值相同,则将两个记录进行关联,生成结果。 hashJoin的优点是在内存充足的情况下,处理大规模数据的效率较高。由于哈希表是在内存中构建的,所以可以减少磁盘I/O的开销。此外,它适用于多种关联类型,如内连接、左连接、右连接等。 然而,hashJoin也有一些限制。首先,它需要将整个表进行哈希分区,因此在内存不足的情况下,可能导致性能下降。其次,在进行哈希分区和关联操作时,需要消耗较多的CPU资源。此外,如果两个表中的关联列不具有相同的数据分布,可能导致哈希桶不均匀,进而影响关联操作的效率。 总的来说,MySQL的hashJoin算法是一种高效的关联查询方法,可以在合适的场景下提供较好的性能。但需要注意配置合适的内存大小,并保证关联列的数据分布较为均匀,以达到最佳的运行效果。 ### 回答3: MySQL中的hashJoin是一种用于联接操作的算法。联接操作是将多个表中的数据按照某些条件进行匹配和合并的过程。而hashJoin是其中一种高效的联接算法。 hashJoin的原理是利用哈希表的特性,在内存中构建一个哈希表来存储较小表中的数据。首先,将待联接的两个表中的一个表的数据读入内存并构建哈希表,将哈希表的键值设为联接条件的键值,并将相应的数据行存储在哈希表中。然后,遍历另一个表的数据,对于每一行数据,通过联接条件的键值查找哈希表中是否存在对应的数据行,如果存在,则将两行数据进行合并,并输出结果。 相比于其他联接算法,hashJoin的优点主要体现在以下几个方面: 1. 内存控制:hashJoin将较小表的数据存储在内存中,避免了大规模的磁盘读操作,提高了查询效率。同时,由于使用哈希表存储数据,可以大幅度减少内存的占用空间。 2. 快速查找:哈希表的查找操作具有快速的特性,可以在常数时间内完成查找操作。这使得hashJoin能够在较短的时间内完成联接操作,适用于处理大规模数据的场景。 3. 并行化处理:由于hashJoin的哈希表是在内存中构建的,可以方便地进行并行化处理。可以将不同的数据分配给不同的CPU进行处理,提高了联接操作的并行度和效率。 需要注意的是,hashJoin算法对内存的需求较高,如果内存不足,可能会导致性能下降或者无法完成联接操作。此外,选择合适的联接条件和恰当的索引也会对hashJoin的效率产生影响。因此,在使用hashJoin时,需要根据具体的业务场景和数据特点进行调优和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值