[MYSQL]多表连接的原理
[MYSQL]多表连接的原理
多表连接的方式
//from t1, t2 where . . .
SELECT * FROM
t1, t2
WHERE t1.m = t2.m and . . .;
//(inner) join t2 on . . .
SELECT column_name(s) FROM t1
INNER JOIN t2
ON t1.m = t2.m and t1.m = 2 . . .;
//left join t2 on . . .
SELECT column_name(s) FROM t1
LEFT JOIN t2
ON t1.m = t2.m
//right join t2 on . . .
SELECT column_name(s) FROM t1
RIGHT JOIN t2
ON t1.m = t2.m
//full join t2 on . . .
SELECT column_name(s) FROM t1
FULL JOIN t2
ON t1.m = t2.m and . . .
多表连接的原理
对于两个表连接操作,需要区分驱动表和被驱动表:
驱动表:第一个需要查询的表,执行查询的策略与普通单表查询一致;
被驱动表:针对上一步骤中从驱动表产生的结果集中的每一条记录,需要分别到被驱动表中查找匹配的记录。
在上面的例子中,驱动表和被驱动表分别是:
1) from t1, t2 where . . .
驱动表: t1或t2被驱动表: t1或t2
2) (inner) join t2 on . . .
驱动表: t1或t2被驱动表: t1或t2
3) left join t2 on . . .
驱动表: t1被驱动表: t2
4) right join t2 on . . .
驱动表: t2被驱动表: t1
5) full join t2 on . . .
驱动表: t1或t2被驱动表: t1或t2
一个例子
以下列语句为例,说明(内)连接操作的过程:
SELECT * FROM t1, t2 WHERE t1.m1 > 1 AND t1.m1 = t2.m2 AND t2.n2 < 'd';
mysql> SELECT * FROM t1;
+------+------+
| m1 | n1 |
+------+------+
| 1 | a |
| 2 | b |
| 3 | c |
+------+------+
3 rows in set (0.00 sec)
mysql> SELECT * FROM t2;
+------+------+
| m2 | n2 |
+------+------+
| 2 | b |
| 3 | c |
| 4 | d |
+------+------+
3 rows in set (0.00 sec)
1.假设t1是驱动表,t2是被驱动表。在这个查询中我们指明了这三个过滤条件:
t1.m1 > 1//仅涉及驱动表的条件, 用于驱动表的查询
t1.m1 = t2.m2//涉及两个表的条件, 用于被驱动表的查询
t2.n2 < 'd'//仅涉及被驱动表的条件,用于被驱动表的查询
2.首先要对驱动表t1执行单表查询,其过滤条件是上面三个过滤条件中的t1.m1 > 1,其查询结果为
+------+------+
| m1 | n1 |
+------+------+
| 2 | b |
| 3 | c |
+------+------+
3.上一步骤从驱动表中得到了2条记录,分别需要到t2表中查找匹配的记录,即需要查询2次t2表。此时涉及两个表的列的过滤条件t1.m1 = t2.m2就派上用场了:
当t1.m1 = 2时,过滤条件t1.m1 = t2.m2就相当于t2.m2 = 2,所以此时t2表相当于有了t2.m2 = 2、t2.n2 < 'd'这两个过滤条件,然后到t2表中执行单表查询;
当t1.m1 = 3时,过滤条件t1.m1 = t2.m2就相当于t2.m2 = 3,所以此时t2表相当于有了t2.m2 = 3、t2.n2 < 'd'这两个过滤条件,然后到t2表中执行单表查询。
4.最终的查询结果是:
+------+------+------+------+
| m1 | n1 | m2 | n2 |
+------+------+------+------+
| 2 | b | 2 | b |
| 3 | c | 3 | c |
+------+------+------+------+
内连接与外连接
内连接
SELECT * FROM t1 [INNER | CROSS] JOIN t2 [ON 连接条件] [WHERE 普通过滤条件];
SELECT * FROM t1 , t2 [WHERE 普通过滤条件];
驱动表中的记录如果在被驱动表中没有匹配的记录,则不会被加入到结果集;
包括:1) from t1, t2 where . . .和2) (inner) join t2 on . . .;
ON子句和where子句都是可选的;
ON后面的条件和WHERE后面的条件都是一样的,只需要按照前面所提到的连接原理进行连接即可。
例如以下几个查询的结果都是一致的:
SELECT * FROM t1, t2 WHERE t1.m1 > 1 AND t1.m1 = t2.m2 AND t2.n2 < 'd';
SELECT * FROM t1 JOIN t2 WHERE t1.m1 > 1 AND t1.m1 = t2.m2 AND t2.n2 < 'd';
SELECT * FROM t1 JOIN t2 ON t1.m1 > 1 AND t1.m1 = t2.m2 AND t2.n2 < 'd';
左外连接
SELECT * FROM t1 LEFT [OUTER] JOIN t2 ON 连接条件 [WHERE 普通过滤条件];
放在左边的表称之为外表或者驱动表,右边的表称之为内表或者被驱动表;
必须使用ON子句来指出连接条件,where子句是可选的;
首先使用ON子句的条件进行上面的连接过程(驱动表+被驱动表),得到满足ON连接条件的结果集R1;
对于驱动表中没有满足ON条件的记录,也加入到结果集R1中形成R2;
如果后面有where子句,则再对R2进行筛选形成最终的结果集R。
下面有几个例子:
# 前三条记录满足ON连接条件,后两条记录是驱动表中不满足ON条件的记录,但仍然被加入到最终的结果集中
select * from t1 left join t2 on m1>2;
+------+------+------+------+
| m1 | n1 | m2 | n2 |
+------+------+------+------+
| 3 | c | 2 | b |
| 3 | c | 3 | c |
| 3 | c | 4 | d |
| 1 | a | NULL | NULL |
| 2 | b | NULL | NULL |
+------+------+------+------+
# 这个查询实际是上一个查询加上WHERE筛选条件的结果
select * from t1 left join t2 on m1>2 where m1 <=2;
+------+------+------+------+
| m1 | n1 | m2 | n2 |
+------+------+------+------+
| 1 | a | NULL | NULL |
| 2 | b | NULL | NULL |
+------+------+------+------+
# 第一条记录满足ON连接条件,后两条记录是驱动表中不满足ON条件的记录,但仍然被加入到最终的结果集中
select * from t1 left join t2 on m1>2 and m1=m2;
+------+------+------+------+
| m1 | n1 | m2 | n2 |
+------+------+------+------+
| 3 | c | 3 | c |
| 1 | a | NULL | NULL |
| 2 | b | NULL | NULL |
+------+------+------+------+
右外连接
与左外连接原理相似。
外连接
首先使用ON子句的条件进行上面的连接过程(驱动表+被驱动表),得到满足ON连接条件的结果集R1;
对于驱动表和被驱动表中没有满足ON条件的记录,也加入到结果集R1中形成R2;
如果后面有where子句,则再对R2进行筛选形成最终的结果集R。
[MYSQL]多表连接的原理相关教程
腾讯云数据库备用-基于GTID复制的mysql作为CDB的从库
腾讯云数据库备用-基于GTID复制的mysql作为CDB的从库 原因:腾讯云数据丢失,但是又有业务在腾讯云上,所以需要对数据库进行备份(自建从库,腾讯云的说法),做腾讯云数据库的从库 基于mysql 5.7实现. 1、首先用户通过在控制台创建一个用于复制的账户wjqrepl; 2、
mysql复制原理
mysql复制原理 1. Master接收写操作,写入binlog 2. Slave上IO_THREAD连接master上,请求变更日志 3. IO_thread 接收到日志请求后写入relay-log中 4. slave上SQL_THREAD读取Relay-log,执行里面的SQL,把结果同步到Datafile 转载于:https://blog.51cto.com/94254
Linux下源码安装MySQL
Linux下源码安装MySQL 今天我们来讲解在Linux环境下用源码来安装MySQL 1.下载安装包 首先 我们去官网下载安装包,在上篇文章中有网站安装包的选取及其介绍,这次就不多做介绍。 这次介绍的是7.5版本的。 2.安装开发工具和安装包 因为要把源码编译成二进制数据
最全idea java连接mysql数据库中文乱码解决方案
最全idea java连接mysql数据库中文乱码解决方案 相信不少人都遇到过中文乱码的问题,今天整理一篇解决乱码问题的文章分享给大家 【中文乱码总逃脱不了编码格式以及匹配的问题】 1,修改idea文件编码格式 idea–》File》settings》editor》File Encodings 2,
糟糕!新装的mysql同事居然不能访问?
糟糕!新装的mysql同事居然不能访问? 在自己的开发电脑上装了一个mysql,同事想要连接我的mysql居然被拒绝了!! 1. 检查防火墙。 处于关闭状态,所以不可能是防火墙在作怪。 2.检查两台电脑是否在同一局域网内。 打开cmd,输入 “ping ip地址” 检测 如图,
ThinkPad安装Ubuntu16.04出现无法连接无线网络,搜不到WiFi,无
ThinkPad安装Ubuntu16.04出现无法连接无线网络,搜不到WiFi,无法使用WiFi(已解决) 1、问题描述 ThinkPad L12安装Ubuntu16.04系统,出现无法连接无线网络的现象,搜不到WiFi,无法使用WiFi,如下图所示: 2、解决方法 升级内核、升级WiFi固件 下载地址 升级
技术分享 | 改写 mysqldump 解决 DEFINER 问题
技术分享 | 改写 mysqldump 解决 DEFINER 问题 作者:xuty 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 项目上 MySQL 还原 SQL 备份 经常会碰到一个错误如下,且通常出现在导入视图、函数、存储过程
Unity与MySql交互之一 mysql的安装与配置
Unity与MySql交互之一 mysql的安装与配置 Unity与MySql交互之一 mysql和Navicat的安装与配置 关于Unity与MySql如何交互,可以看这篇博客: https://editor.youkuaiyun.com/md?not_checkout=1articleId=108802823 最近在使用MySql,发现有些同行不知道 怎么进到MySq