为什么需要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两张表,我们可以看到有三种情形:

  1. person表中的人购买了商品,也就是order表中有关于该用户的商品购买记录,我们可以从该表中查询到该用户买了哪些商品,如andy Chen购买了book和phone两种商品,即pid在tb_person和tb_order两种表中都存在;

  2. person表中的人未购买商品,如irri Wan和abby Sun两位用户并未购买任何商品,即pid只存在于tb_person表;

  3. 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用法简介的更多相关文章

  1. MySQL基础之STRAIGHT JOIN用法简介

    MySQL基础之STRAIGHT JOIN用法简介 引用mysql官方手册的说法: STRAIGHT_JOIN is similar to JOIN, except that the left tab ...

  2. MySQL应用之CROSS JOIN用法简介教程

    目录 2. cross join用法 @ 本博客翻译自两篇博客的: http://www.mysqltutorial.org/mysql-cross-join/ https://www.w3resou ...

  3. MySQL join 用法

    select column1, column2 from TABLE1 join TABLE2 on 条件 # select * from table1 join table2; #两个表合成一个se ...

  4. 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 ...

  5. sleep、yield、join方法简介与用法 sleep与wait区别 多线程中篇(十五)

    Object中的wait.notify.notifyAll,可以用于线程间的通信,核心原理为借助于监视器的入口集与等待集逻辑 通过这三个方法完成线程在指定锁(监视器)上的等待与唤醒,这三个方法是以锁( ...

  6. mysql学习之join用法

    转载  一张图看懂 SQL 的各种 join 用法 一.JOIN 使用介绍 下面例子使用的数据表如下: -- ---------------------------- -- Table structu ...

  7. mysql中left join right join inner join用法分析

    mysql数据库中的关联查询,基本都会用到left join,right join,inner join等查询方式,今天来说说这三种用法的区别 1.创建表test1,test2,插入测试数据 #创建表 ...

  8. MySQL变量介绍和用法简介

    目录 一.用户变量 1.1.用户变量定义 1.2.用户变量用法 二.系统变量 2.1 系统变量简单介绍 2.2 系统变量用法简介 本博客介绍一下MySQL中变量的用法和注意细节 @ 一.用户变量 1. ...

  9. 【转载】 mysql explain用法

    转载链接:  mysql explain用法 官网说明:     http://dev.mysql.com/doc/refman/5.7/en/explain-output.html 参数:  htt ...

随机推荐

  1. 如何大幅提升web前端性能之看tengine在大公司架构实践

    在一个项目还是单体架构的时候,所有的js,css,image都会在一个web网站上,看起来并没有什么问题,比如下面这样: 但是当web网站流量起来的时候,这个单体架构必须要进行横向扩展,而在原来的架构 ...

  2. 记一次按需加载和npm模块发布实践

    按需加载 在使用 lodash 的时候我们可以使用这样的代码 //一 import {omit} from "lodash"; //二 import l from "lo ...

  3. 从0开始用U盘制作启动盘装Windows10系统(联想R720笔记本)并永久激活方法

    一,制作U盘启动盘 随着个人电脑的“飞入寻常百姓家”,喜欢DIY电脑的发烧友们也越来越多. 安装系统是DIY最基本的要求,很容易做到: 那么如果要求用U盘装系统呢,你可能会说简单,直接下载个老毛桃或是 ...

  4. arcgis api for js入门开发系列二十打印地图的那些事

    前面我写过关于利用arcgis api for js打印地图的,但是打印地图服务都是基于arcgis server发布的,arcgis api加载在线地图,比如天地图.百度地图.高德地图等,底图都是打 ...

  5. 源码浅谈(二):java中的 Integer.parseInt(String str)方法

    这个方法是将字符串转换为整型 一.parseInt方法 ,可以看到默认又调用了parseInt(s,10) ,  第二个参数为基数,默认10 ,当然也可以自己设置  public static int ...

  6. Android破解学习之路(十四)——【Unity3D】王牌大作战破解

    一.前言 今天带来的是王牌大作战的破解教程,游戏下载的话,我是直接去TapTap官网下载的 支付宝内购破解用老套了,今天学点破解的新花样吧!! 二.支付宝内购破解 支付宝的内购破解已经很熟悉了, 直接 ...

  7. 章节十、3-CSS Selector---用CSS Selector - ID定位元素

    一.如果元素的 ID 不唯一,或者是动态的,或者 name 以及 linktext 属性值也不唯一,对于这样的元素,我们 就需要考虑用 xpath或者css selector 来查找元素了,然后再对元 ...

  8. JPA实现复杂条件分页查询

    相信熟悉Hibernate的人对于ORM给编程带来的便利于快捷一定不陌生,相对于MyBatis等需要编写复杂的SQL语句,ORM映射为我们带来的便利显而易见.但是,在获得便利的同时,失去的便是灵活性, ...

  9. windows2012R2安装SQL2005详情!

    用友T3软件报错单据的时候提示1105数据库错误 原因分析:客户使用的是sql2005 express的数据库,账套的物理文件达到了4G. 只能重装SQL的版本,but.... 在window2012 ...

  10. SQLServer之创建Transact-SQL游标

    什么是游标 结果集,结果集就是select查询之后返回的所有行数据的集合. 游标则是处理结果集的一种机制吧,它可以定位到结果集中的某一行,多数据进行读写,也可以移动游标定位到你所需要的行中进行操作数据 ...