MySql join 详解
数据库中的join
成为连接,连接的主要作用是根据两个或多个表中的列之间的关系,获取存在于不同表中的数据。连接分为三类:内连接、外连接、全连接
上图
数据准备
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 |
-- 创建测试数据库 CREATE DATABASE join_test CHARSET UTF8;-- 人员信息表 CREATE TABLE `Persons` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`LastName` char(16) NOT NULL DEFAULT '',`FirstName` char(16) NOT NULL DEFAULT '',`Address` varchar(128) NOT NULL DEFAULT '',`City` varchar(128) NOT NULL DEFAULT '',PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- 订单表 CREATE TABLE `Orders` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`OrderNo` int(11) NOT NULL DEFAULT '0',`Pid` int(11) NOT NULL DEFAULT '0',PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;INSERT INTO `Persons` (`LastName`, `FirstName`, `Address`, `City`) VALUES ('Adams', 'John', 'Oxford Street', 'London'), ('Bush', 'George', 'Fifth Avenue', 'New York'), ('Carter', 'Thomas', 'Changan Street', 'Beijing');INSERT INTO `Orders` (`OrderNo`, `Pid`) VALUES (77895, 3), (44678, 3), (22456, 1), (24562, 1), (34764, 65); |
Persons表
Orders表
数据库中的join
成为连接,连接的主要作用是根据两个或多个表中的列之间的关系,获取存在于不同表中的数据。连接分为三类:内连接、外连接、全连接
内连接(图-3)
内连接在SQL中是JOIN
|INNER JOIN
; INNER JOIN
与 JOIN
的查询结果都是相同的,也就是说两个的作用都是一样的。
内连接查询返回两个表中在ON
后面指定的列条件相同时的行;
例如:
1 2 3 4 |
SELECT Persons.id, Persons.LastName, Persons.FirstName, Orders.id,Orders.OrderNo,Orders.Pid FROM Persons INNER JOIN Orders ON Persons.id = Orders.Pid |
查询的结果:
或者
1 2 3 4 |
SELECT Persons.id, Persons.LastName, Persons.FirstName, Orders.id,Orders.OrderNo,Orders.Pid FROM Persons JOIN Orders ON Persons.id = Orders.Pid |
结果:
从这结果中可以看到:
- 首先,我们发现
INNER JOIN
和JOIN
的查询结果确实是一致的; - 其次,
INNER JOIN
和JOIN
关键字在表中存在至少一个匹配时返回行。如果Persons
中的行在Orders
中没有匹配,就不属于内连接查询的结果,就不会列出相应的Persons
或Orders
这些行。简言之,查询的结果集是符合ON
之后条件时的所有行,A表中的某一条记录对应B表中的多个记录会以重复的方式对应不同的多条B表记录出现在结果集中,B表中的一条记录对应A表中的多条记录时会以多条A表记录对应相同B表记录的方式出现在结果集中。
外连接(图-1、2)
外连接分为 左外连接LEFT JOIN
和 右外连接RIGHT JOIN
。虽然是两种写法,但他们之间是可以转换的,其实是互相的变形。
LEFT JOIN
关键字会从左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中没有匹配的行。LEFT JOIN 也写作 LEFT OUTER JOINRIGHT JOIN
关键字会右表 (table_name2) 那里返回所有的行,即使在左表 (table_name1) 中没有匹配的行。RIGHT JOIN 也写作 RIGHT OUTER JOIN
我们以左外连接示例说明,然后写一个查询结果一样的右外连接说明他两确实是可以转化的;左外连接和右外连接关键的区别实在 主表的确定:
- 左外连接是以
LEFT JOIN
左侧也就是前面的表(FROM后面的跟的表)作为主表,返回所有左侧表中的记录,右侧表中不存在匹配时在相应字段不NULL
。 左侧表可能在右侧表中对应多条记录,那么就在结果集中以相同左侧表记录不同右侧表记录多条显示在结果集中;也可能左侧表记录在右侧没有一条匹配,那么就会返回所有左侧表记录,右侧表的字段都以NULL
替代;所以在没有WHERE
条件时,mysql查询的结果集或者说临时表的记录一定是大于或等于左侧表记录数的。 - 右外连接是以
RIGHT JOIN
右侧也就是后面的表(RIGHT JOIN后面的跟的表)作为主表,返回所有右侧表中的记录,左侧表中不存在匹配时在相应字段不NULL
。
左外连接:
1 2 3 4 |
SELECT Persons.id, Persons.LastName, Persons.FirstName, Orders.id,Orders.OrderNo,Orders.Pid FROM Persons LEFT JOIN Orders ON Persons.id = Orders.Pid |
结果:
右外连接:
1 2 3 4 |
SELECT Persons.id, Persons.LastName, Persons.FirstName, Orders.id,Orders.OrderNo,Orders.Pid FROM Persons RIGHT JOIN Orders ON Persons.id = Orders.Pid |
结果:
现在我们对上面的左外连接做一个相同结果的右外连接转化
右外连接:
1 2 3 4 |
SELECT Persons.id, Persons.LastName, Persons.FirstName, Orders.id,Orders.OrderNo,Orders.Pid FROM Orders RIGHT JOIN Persons ON Persons.id = Orders.Pid |
结果:
结果是不是和上面的左外连接一样啊!仔细理解就会发现:Persons
对Orders
的左外连接 其实就相当于 Orders
对Persons
的右外连接;两者的主表都是Persons
表,所以转换的关键是保证左外连接和右外连接的主表是相同的即可。
全连接(图-4)
首先注意:mysql并不支持全连接,但是有相应的替代策略:利用UNION
联合查询,下面给出mysql关于连接查询的参考资料:
- 14.2.9 SELECT Syntax
- 14.2.9.2 JOIN Syntax
虽然mysql不支持,但还是说明一下FULL JOIN
:
FULL JOIN
全连接会从左表 (Persons) 和右表 (Orders) 那里返回所有的行。如果 Persons
中的行在表 Orders
中没有匹配,或者如果 Orders
中的行在表 Persons
中没有匹配,这些行同样会列出,不存在的字段会以NULL
补充。
也就是说当连接的两个表的记录匹配项时,它们会组合成结果集中的一条记录,如果两张表中的某些记录在对方表中都不存在匹配时,它们也会被查询出来放大结果集中,只是在这些记录的另一个表中的字段信息是NULL
补充的。
1 2 3 4 |
SELECT Persons.id, Persons.LastName, Persons.FirstName, Orders.id,Orders.OrderNo,Orders.Pid FROM Persons RIGHT JOIN Orders ON Persons.id = Orders.Pid |
ok,mysql关于FULL JOIN的替代策略:就是左外连接和右外连接的联合查询
1 2 3 4 5 6 7 8 9 10 11 12 |
SELECT * FROM Persons LEFT JOIN Orders ON Persons.id = Orders.Pid UNION SELECT * FROM Persons RIGHT JOIN Orders ON Persons.id = Orders.Pid-- 模式就是这样 SELECT * FROM t1 LEFT JOIN t2 ON t1.id = t2.id UNION SELECT * FROM t1 RIGHT JOIN t2 ON t1.id = t2.id |
结果:
总结
- 对于三类连接查询,MySQL只支持其中的:内连接 和 外连接
- 对于所有的连接类型而言,就是将符合关键字
ON
后条件匹配的对应组合都成为一条记录出现在结果集中,对于两个表中的某条记录可能存在:一对多 或者 多对一 的情况会在结果集中形成多条记录,只是另外一个表中查询的字段信息相同而已;千万不要误以为:左外连接查询到的记录数是和左表的记录数一样,对于其他连接一样,不能形成这个误区。 - 对于内连接查询到的是一个符合
ON
条件匹配的在两个表中都存在记录的结果集 - 对于外连接,例如左外连接查询到的是一个包含所有左表记录且在右表符合
ON
匹配时的右表信息的结果集,如果左表的某条记录和右表的多条记录匹配,结果集中就存在同一个左表记录对应多个右表记录的多条记录,此时的结果集记录数是大于左表的记录数的。对于右外连接来说同理。 - 对于全连接,就是把左表右表都包含在内,如果符合
ON
条件的匹配在结果集中形成一条记录,如果对左表或者右表中的某一条记录在对方表中不存在ON
匹配时,就以单独一条记录出现在结果集中,对方表不存在的信息以NULL
补充。
MySql join 详解相关推荐
- MySQL Join详解
背景 最近有很多业务查询需要用到连表join,由于数据量都不是很大,而且肉眼可见的生命周期内,也没有需要分布式分库分表的可能性,故而仍然直接使用了join语句进行数据查询,但是在我印象中,出现过很多不 ...
- Mysql Explain 详解
Mysql Explain 详解 一.语法 explain < table_name > 例如: explain select * from t3 where id=3952602; 二. ...
- MySQL Explain详解,分析语句为何运行慢
MySQL Explain详解 在日常工作中,我们会有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这些SQL语句并不意味着完事了,些时我们常常用到explain这个命令来查看一个这些SQL语 ...
- 史上最简单MySQL教程详解(进阶篇)之索引及失效场合总结
史上最简单MySQL教程详解(进阶篇)之索引及其失效场合总结 什么是索引及其作用 索引的种类 各存储引擎对于索引的支持 简单介绍索引的实现 索引的设置与分析 普通索引 唯一索引(Unique Inde ...
- 史上最简单MySQL教程详解(进阶篇)之视图
史上最简单MySQL教程详解(进阶篇)之视图 为什么要用视图 视图的本质 视图的作用 如何使用视图 创建视图 修改视图 删除视图 查看视图 使用视图检索 变更视图数据 WITH CHECK OPTIO ...
- MySQL数据库,从入门到精通:第十四篇——MySQL视图详解
MySQL数据库,从入门到精通:第十四篇--MySQL视图详解 第 14 篇_视图 1. 常见的数据库对象 2. 视图概述 2. 1 为什么使用视图? 2. 2 视图的理解 3. 创建视图 3. 1 ...
- MySQL Explain详解,explain查询结果每列含义详细解释
转自:https://www.cnblogs.com/xuanzhi201111/p/4175635.html MySQL Explain详解 在日常工作中,我们会有时会开慢查询去记录一些执行时间比较 ...
- 十六、MySQL 视图详解
文章目录 一.常见的数据库对象 二.视图概述 2.1 为什么要使用视图? 2.2 视图的理解 2.3 视图的作用 三.视图常用操作 3.1 查看创建视图的权限 3.2 创建视图 3.3 查看视图 3. ...
- pandas读写MySQL数据库详解及实战
pandas读写MySQL数据库详解及实战 SQLAlchemy是Python中最有名的ORM工具. 关于ORM: 全称Object Relational Mapping(对象关系映射). 特点是操纵 ...
- MySQL存储过程详解 mysql 存储过程
mysql存储过程详解 1. 存储过程简介 我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的S ...
最新文章
- alias用法和对当前用户的永久配置
- 常用Git指令常用git命令清单
- Jquery操作复选框总结
- sqlserver安装显示句柄无效_Sqlserver 2016 R Service环境安装的各种错误(坑)解决办法...
- android 加载图片并在上面画图
- JavaScript学习(二十七)—解决IE以及IE8之前的浏览器下面的添加事件或者删除事件
- 如何禁用Web表单字段/输入标签上的浏览器自动完成功能?
- 有趣的二进制—高效位运算
- Vue 事件绑定 事件修饰符 条件判断 循环遍历
- 数字化定量分析_数字化定量分析
- 最新emoji表情代码大全_在 Markdown 中使用表情符号
- Spring Thymeleaf无法显示图片
- 四川2021年高考成绩位次查询,2021年填报志愿数据:四川所有本科大学近三年分数线、对应位次排行榜...
- Web前端全栈开发_node源码笔记【爱创课堂】
- Eclipse创建C++工程并解决“Symbol 'std' could not be solved”
- 主板没有rgb接口怎么接灯_DIY只为玩游戏?主板配上RGB灯让机箱发光
- 米尔基于ARM架构核心板的国产化EtherCAT主站控制器解决方案
- GitHub中已开源项目汇总
- 做一条USB A转Type C 数据线 和OTG线
- 【MATLAB教程案例13】基于SA模拟退火优化算法的函数极值计算matlab仿真及其他应用
热门文章
- 到底什么是非线性优化?
- MIKE 21 教程 2.5 水动力模块教学:涡粘系数(Eddy viscosity),河床阻力与曼宁系数(Bed Resistance)
- Ubuntu下切换root用户认证失败解决方案
- 安装Activemq5.13.2异常
- 《假装情侣匿名聊天室2.0》源码及搭建教程
- 重庆大Vseo这么多年的seo心得
- ERROR: Error while obtaining start requests
- 403forbidden提示没有权限
- 如何从零构建对内网穿透的理解
- BOOST元状态机用户手册之三教程(Meta State Machine (MSM))(1)——基本前端及例程