mysql join用法简介
为什么需要join
为什么需要join?join中文意思为连接,连接意味着关联即将一个表和多个表之间关联起来。在处理数据库表的时候,我们经常会发现,需要从多个表中获取信息,将多个表的多个字段数据组装起来再返回给调用者。所以join的前提是这些表之间必须有关联字段。
join的分类
join分为两种,inner join和outer join,其中outer join分为三种,left outer join, right outer join, full outer join,另外left outer join又简称为left join即大家所熟知的左连接。
各种join的区别
在介绍各种join的区别之前,我们先来看一个简单的示例:
场景描述:
互联网时代,大家都喜欢在网上购物,尤其是淘宝和京东,所以我们选择的场景也是大家熟悉的网上购物。这是一个关于一个人和他在商城买了什么商品的一个故事;
针对上述需求,我们建立了两张表,tb_person和tb_order,其中tb_person是关于这个人的描述,tb_order是关于他购买的商品的一个描述。
我们的表结构很简单,tb_person只需要知道这个人是谁就可以了,所以只有三个字段id,firstname(名)和lastname(姓),同样tb_order也很简单,我们只要知道谁买了什么商品,所以只需要3个字段,分别是oid, oname(商品名称), pid(购买者编号)。
tb_person:
1
2
3
4
5
6
7
|
+ -----------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | + -----------+-------------+------+-----+---------+----------------+ | pid | int (11) | NO | PRI | NULL | auto_increment | | firstname | varchar (50) | YES | | NULL | | | lastname | varchar (50) | YES | | NULL | | + -----------+-------------+------+-----+---------+----------------+ |
tb_order:
1
2
3
4
5
6
7
|
+ -------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | + -------+-------------+------+-----+---------+----------------+ | oid | int (11) | NO | PRI | NULL | auto_increment | | oname | varchar (50) | YES | | NULL | | | pid | int (11) | YES | | NULL | | + -------+-------------+------+-----+---------+----------------+ |
接下来,我们向上述两张表中写入一些示例数据:
data in tb_person:
1
2
3
4
5
6
7
|
+ -----+-----------+----------+ | pid | firstname | lastname | + -----+-----------+----------+ | 1 | andy | chen | | 2 | irri | wan | | 3 | abby | sun | + -----+-----------+----------+ |
tb_person表中有三位人员,分别是andy Chen, irri Wan, abby Sun;
data in tb_order:
1
2
3
4
5
6
7
|
+ -----+----------+------+ | oid | oname | pid | + -----+----------+------+ | 1 | book | 1 | | 2 | phone | 1 | | 3 | computer | 4 | + -----+----------+------+ |
tb_order表中记录了3条数据,人员编号为1也就是andy Chen买了两件商品分别是book和phone,另外还有一个人员编号为4的人买了一件商品computer。关于这个大家可能会产生疑问,为什么tb_person表中没有人员编号为4的人呢?这里我们姑且认为由于注册用户较多,我们采用了用户分表策略,所以人员编号为4的用户可能在另外一张人员表中。
从之前的描述我们知道,表与表之间如果要join则必须要有关联的字段,上述示例我们看到这个关联的字段就是pid。
根据tb_person和tb_order两张表,我们可以看到有三种情形:
person表中的人购买了商品,也就是order表中有关于该用户的商品购买记录,我们可以从该表中查询到该用户买了哪些商品,如andy Chen购买了book和phone两种商品,即pid在tb_person和tb_order两种表中都存在;
person表中的人未购买商品,如irri Wan和abby Sun两位用户并未购买任何商品,即pid只存在于tb_person表;
order表中购买商品的用户在person表中找不到记录,如pid为4的用户购买了一台computer但在tb_person表中没有该用户的记录,即pid只存在于tb_order表;
理解上述三种情形对于我们理解join有非常大的帮助,接下来我们将具体的分析每种join的区别:
INNER JOIN
所谓inner join的意思就是我们前面提到的情形1,pid必须在tb_person和tb_order两张表中同时存在;
1
2
3
4
|
MariaDB [demo]> SELECT p.pid, p.firstname, o.oname -> FROM tb_person p -> INNER JOIN tb_order o -> ON p.pid=o.pid; |
1
2
3
4
5
6
|
+ -----+-----------+-------+ | pid | firstname | oname | + -----+-----------+-------+ | 1 | andy | book | | 1 | andy | phone | + -----+-----------+-------+ |
LEFT JOIN
tb_person LEFT JOIN tb_order的意思是上述情形1,情形2的并集。LEFT JOIN的结果集不仅包含INNER JOIN的结果,而且还包含所有tb_person中没有购买任何商品的用户集。
1
2
3
4
|
MariaDB [demo]> SELECT p.pid, p.firstname, o.oname -> FROM tb_person p -> LEFT JOIN tb_order o -> ON p.pid=o.pid; |
1
2
3
4
5
6
7
8
|
+ -----+-----------+-------+ | pid | firstname | oname | + -----+-----------+-------+ | 1 | andy | book | | 1 | andy | phone | | 2 | irri | NULL | | 3 | abby | NULL | + -----+-----------+-------+ |
RIGHT JOIN
tb_person RIGHT JOIN tb_order的意思是上述情形1和情形3的并集。RIGHT JOIN的结果集不仅包含INNER JOIN的结果,而且还包含所有tb_order中所有已经购买商品的用户但该用户记录不存在于tb_person表。
1
2
3
4
|
MariaDB [demo]> SELECT p.pid, p.firstname, o.oname -> FROM tb_person p -> RIGHT JOIN tb_order o -> ON p.pid=o.pid; |
1
2
3
4
5
6
7
|
+ ------+-----------+----------+ | pid | firstname | oname | + ------+-----------+----------+ | 1 | andy | book | | 1 | andy | phone | | NULL | NULL | computer | + ------+-----------+----------+ |
FULL JOIN
故名思议,FULL JOIN就是上述情形1,2,3的并集了,但是mysql数据库不支持full join查询,所以我们只能LEFT JOIN union RIGHT JOIN,才能得到FULL JOIN的结果。
1
2
3
4
5
6
7
8
9
|
MariaDB [demo]> SELECT p.pid, p.firstname, o.oname -> FROM tb_person p -> LEFT JOIN tb_order o -> ON p.pid=o.pid -> UNION -> SELECT p.pid, p.firstname, o.oname -> FROM tb_person p -> RIGHT JOIN tb_order o -> ON p.pid=o.pid; |
1
2
3
4
5
6
7
8
9
|
+ ------+-----------+----------+ | pid | firstname | oname | + ------+-----------+----------+ | 1 | andy | book | | 1 | andy | phone | | 2 | irri | NULL | | 3 | abby | NULL | | NULL | NULL | computer | + ------+-----------+----------+ |
注:我们上述的sql语句全部基于mysql数据库执行。
总结
本文主要描述了sql join的分类以及各种join的区别,通过简单的示例,让大家更清晰的去了解他们。至于什么时候使用join要视具体的情况而定,根据不同的需求采用不同的策略。
非常感谢大家的热心回复,可能有些问题的探讨超出了本文的范畴,但是非常乐意大家提出问题,然后大家一起去探索去发现。
引用
NULL
附件
demo.sql文件
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
|
create database demo; use demo; create table tb_person ( pid int (11) auto_increment, firstname varchar (50), lastname varchar (50), primary key (pid) ); create table tb_order ( oid int (11) auto_increment, oname varchar (50), pid int (11), primary key (oid) ); insert into tb_person(firstname, lastname) values ( 'andy' , 'chen' ); insert into tb_person(firstname, lastname) values ( 'irri' , 'wan' ); insert into tb_person(firstname, lastname) values ( 'abby' , 'sun' ); insert into tb_order(oname, pid) values ( 'book' , 1); insert into tb_order(oname, pid) values ( 'phone' , 1); insert into tb_order(oname, pid) values ( 'computer' , 4); |
mysql join用法简介的更多相关文章
- MySQL基础之STRAIGHT JOIN用法简介
MySQL基础之STRAIGHT JOIN用法简介 引用mysql官方手册的说法: STRAIGHT_JOIN is similar to JOIN, except that the left tab ...
- MySQL应用之CROSS JOIN用法简介教程
目录 2. cross join用法 @ 本博客翻译自两篇博客的: http://www.mysqltutorial.org/mysql-cross-join/ https://www.w3resou ...
- MySQL join 用法
select column1, column2 from TABLE1 join TABLE2 on 条件 # select * from table1 join table2; #两个表合成一个se ...
- left join,right join用法简介
方法一(推荐): select a.man_id,man_name,d.sex_name,zw_name,c.money from man as a left join zw as b on a.zw ...
- sleep、yield、join方法简介与用法 sleep与wait区别 多线程中篇(十五)
Object中的wait.notify.notifyAll,可以用于线程间的通信,核心原理为借助于监视器的入口集与等待集逻辑 通过这三个方法完成线程在指定锁(监视器)上的等待与唤醒,这三个方法是以锁( ...
- mysql学习之join用法
转载 一张图看懂 SQL 的各种 join 用法 一.JOIN 使用介绍 下面例子使用的数据表如下: -- ---------------------------- -- Table structu ...
- mysql中left join right join inner join用法分析
mysql数据库中的关联查询,基本都会用到left join,right join,inner join等查询方式,今天来说说这三种用法的区别 1.创建表test1,test2,插入测试数据 #创建表 ...
- MySQL变量介绍和用法简介
目录 一.用户变量 1.1.用户变量定义 1.2.用户变量用法 二.系统变量 2.1 系统变量简单介绍 2.2 系统变量用法简介 本博客介绍一下MySQL中变量的用法和注意细节 @ 一.用户变量 1. ...
- 【转载】 mysql explain用法
转载链接: mysql explain用法 官网说明: http://dev.mysql.com/doc/refman/5.7/en/explain-output.html 参数: htt ...
随机推荐
- Golang之轻松化解defer的温柔陷阱
目录 什么是defer? 为什么需要defer? 怎样合理使用defer? defer进阶 defer的底层原理是什么? 利用defer原理 defer命令的拆解 defer语句的参数 闭包是什么? ...
- [开发技巧]·Numpy广播机制的深入理解与应用
[开发技巧]·Numpy广播机制的深入理解与应用 1.问题描述 我们在使用Numpy进行数据的处理时,经常会用到广播机制来简化操作,例如在所有元素都加上一个数,或者在某些纬度上作相同的操作.广播机制很 ...
- Linux权限管理(week1_day5)--技术流ken
权限概述 Linux系统一般将文件可存/取访问的身份分为3个类别:owner(拥有者).group(和所有者同组的用户).others(其他人,除了所有者,除了同组的用户以及除了超级管理员),且3种身 ...
- docker (2) 通用/镜像命令
Docker 的常用命令: (1)Docker help 命令: 可以查看有关docker的所有操作命令: (2)docker COMMAND -–help 查看docker 的某项命令的帮助文档 ...
- oracle学习笔记(六) JDBC使用
JDBC使用 1. 导包 直接使用IDEA导入依赖包即可 新建一个lib,把jar包放在这里 2. 加载驱动 Class.forName("oracle.jdbc.driver.Oracle ...
- 你应该学会的Python多版本管理工具Pyenv
目录 Pyenv 简介 安装pyenv 通过pyenv安装python各种发行版 pyenv命令 多版本Python的管理 Pyenv常见问题Wiki Pyenv 简介 首先,该工具是在类linux环 ...
- openlayers二:添加矢量图形文字
openlayers可方便的在地图上添加圆.多边形.文字等矢量内容,修改这些矢量内容的样式也很简单. 首先需要添加一个向量图层: initVectorLayer: function () { this ...
- 碰到了通过Movie显示gif图片,有部分图片的duration为0导致gif只显示第一帧
解决办法,改为使用android-gif-drawable.jar来显示gif图片(需要配合com.android.support:support-v4:18.0.0使用) GifImageView ...
- 在react中实现打印功能
最近项目中,前端采用react+antd+dva的组合,已经完成了后头管理类系统产品的更新迭代工作. 今天有一个新需求,需要在后台管理系统中实现点击打印完成指定页面的打印功能. 之前也没接触过,只知道 ...
- Java关于字符串工具类~持续汇总~
/** * 01 * 描述:String的substring和replace方法使用 * [时间 2019年3月5日下午3:22:08 作者 陶攀峰] */ public static void te ...