SQL JOIN 简单介绍

前言

本文还是秉持之前一贯的写作风格,以简单易懂的示例帮助大家了解各种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| Field     | Type        | Null | Key | Default | Extra          | 3+-----------+-------------+------+-----+---------+----------------+ 4| pid       | int(11)     | NO   | PRI | NULL    | auto_increment | 5| firstname | varchar(50) | YES  |     | NULL    |                | 6| lastname  | varchar(50) | YES  |     | NULL    |                | 7+-----------+-------------+------+-----+---------+----------------+

tb_order:

1+-------+-------------+------+-----+---------+----------------+ 2| Field | Type        | Null | Key | Default | Extra          | 3+-------+-------------+------+-----+---------+----------------+ 4| oid   | int(11)     | NO   | PRI | NULL    | auto_increment | 5| oname | varchar(50) | YES  |     | NULL    |                | 6| pid   | int(11)     | YES  |     | NULL    |                | 7+-------+-------------+------+-----+---------+----------------+

接下来,我们向上述两张表中写入一些示例数据:

data in tb_person:

1+-----+-----------+----------+ 2| pid | firstname | lastname | 3+-----+-----------+----------+ 4|   1 | andy      | chen     | 5|   2 | irri      | wan      | 6|   3 | abby      | sun      | 7+-----+-----------+----------+

tb_person表中有三位人员,分别是andy Chen, irri Wan, abby Sun;

data in tb_order:

1+-----+----------+------+ 2| oid | oname    | pid  | 3+-----+----------+------+ 4|   1 | book     |    1 | 5|   2 | phone    |    1 | 6|   3 | computer |    4 | 7+-----+----------+------+

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两张表中同时存在;

1MariaDB [demo]> SELECT p.pid, p.firstname, o.oname 2    -> FROM tb_person p 3    -> INNER JOIN tb_order o 4    -> ON p.pid=o.pid; 5 6+-----+-----------+-------+ 7| pid | firstname | oname | 8+-----+-----------+-------+ 9|   1 | andy      | book  | 10|   1 | andy      | phone | 11+-----+-----------+-------+

LEFT JOIN

tb_person LEFT JOIN tb_order的意思是上述情形1,情形2的并集。LEFT JOIN的结果集不仅包含INNER JOIN的结果,而且还包含所有tb_person中没有购买任何商品的用户集。

1MariaDB [demo]> SELECT p.pid, p.firstname, o.oname 2    -> FROM tb_person p 3    -> LEFT JOIN tb_order o 4    -> ON p.pid=o.pid; 5 6+-----+-----------+-------+ 7| pid | firstname | oname | 8+-----+-----------+-------+ 9|   1 | andy      | book  | 10|   1 | andy      | phone | 11|   2 | irri      | NULL  | 12|   3 | abby      | NULL  | 13+-----+-----------+-------+

RIGHT JOIN

tb_person RIGHT JOIN tb_order的意思是上述情形1和情形3的并集。RIGHT JOIN的结果集不仅包含INNER JOIN的结果,而且还包含所有tb_order中所有已经购买商品的用户但该用户记录不存在于tb_person表。

1MariaDB [demo]> SELECT p.pid, p.firstname, o.oname 2    -> FROM tb_person p 3    -> RIGHT JOIN tb_order o 4    -> ON p.pid=o.pid; 5 6+------+-----------+----------+ 7| pid  | firstname | oname    | 8+------+-----------+----------+ 9|    1 | andy      | book     | 10|    1 | andy      | phone    | 11| NULL | NULL      | computer | 12+------+-----------+----------+

FULL JOIN

故名思议,FULL JOIN就是上述情形1,2,3的并集了,但是mysql数据库不支持full join查询,所以我们只能LEFT JOIN union RIGHT JOIN,才能得到FULL JOIN的结果。

1MariaDB [demo]> SELECT p.pid, p.firstname, o.oname 2    -> FROM tb_person p 3    -> LEFT JOIN tb_order o 4    -> ON p.pid=o.pid 5    -> UNION 6    -> SELECT p.pid, p.firstname, o.oname 7    -> FROM tb_person p 8    -> RIGHT JOIN tb_order o 9    -> ON p.pid=o.pid; 10 11+------+-----------+----------+ 12| pid  | firstname | oname    | 13+------+-----------+----------+ 14|    1 | andy      | book     | 15|    1 | andy      | phone    | 16|    2 | irri      | NULL     | 17|    3 | abby      | NULL     | 18| NULL | NULL      | computer | 19+------+-----------+----------+

注:我们上述的sql语句全部基于mysql数据库执行。

总结

本文主要描述了sql join的分类以及各种join的区别,通过简单的示例,让大家更清晰的去了解他们。至于什么时候使用join要视具体的情况而定,根据不同的需求采用不同的策略。

非常感谢大家的热心回复,可能有些问题的探讨超出了本文的范畴,但是非常乐意大家提出问题,然后大家一起去探索去发现。

引用

NULL

如果您对算法或编程感兴趣,欢迎扫描下方二维码并关注公众号“算法与编程之美”,和您一起探索算法和编程的神秘之处,给您不一样的解题分析思路。

附件

demo.sql文件

1create database demo; 2use demo; 3 4create table tb_person ( 5    pid int(11) auto_increment, 6    firstname varchar(50), 7    lastname varchar(50), 8    primary key(pid) 9); 10 11create table tb_order ( 12    oid int(11) auto_increment, 13    oname varchar(50), 14    pid int(11), 15    primary key(oid) 16); 17 18insert into tb_person(firstname, lastname) values('andy','chen'); 19insert into tb_person(firstname, lastname) values('irri','wan'); 20insert into tb_person(firstname, lastname) values('abby','sun'); 21 22 23insert into tb_order(oname, pid) values('book', 1); 24insert into tb_order(oname, pid) values('phone', 1); 25insert into tb_order(oname, pid) values('computer', 4);
点赞
收藏

评论区

加载中...

相关推荐

sql join

1.1.1摘要Join是关系型数据库系统的重要操作之一,SQLServer中包含的常用Join:内联接、外联接和交叉联接等。如果我们想在两个或以上的表获取其中从一个表中的行与另一个表中的行匹配的数据,这时我们应该考虑使用Join,因为Join具体联接表或函数进行查询的特性本文将通过具体例子介绍SQL中的各种常用Join的特性和使

MySQL数据库查询

MySQL数据库查询12、说明:使用外连接A、left(outer)join:左外连接(左连接):包含leftjoin左表所有行,如果左表中某行在右表没有匹配,则结果中对应行右表的部分全部为空(NULL).。SQL:select\fromstudent(表1)leftjoincourse(表2)onstude

SQL的各种连接Join详解

原文地址:https://www.cnblogs.com/reaptomorrowflydream/p/8145610.htmlSQLJOIN子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段。最常见的JOIN类型:SQLINNERJOIN(简单的JOIN)、SQLLEFTJOIN、SQL RIGHTJOIN

SQL的各种连接Join详解

原文地址:https://www.cnblogs.com/reaptomorrowflydream/p/8145610.htmlSQLJOIN子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段。最常见的JOIN类型:SQLINNERJOIN(简单的JOIN)、SQLLEFTJOIN、SQL RIGHTJOIN

Flink 双流 Join 的3种操作示例

在数据库中的静态表上做OLAP分析时,两表join是非常常见的操作。同理,在流式处理作业中,有时也需要在两条流上做join以获得更丰富的信息。FlinkDataStreamAPI为用户提供了3个算子来实现双流join,分别是:join()coGroup()intervalJoin()本文举例说明它们的使

SparkSQL的3种Join实现

引言Join是SQL语句中的常用操作,良好的表结构能够将数据分散在不同的表中,使其符合某种范式,减少表冗余、更新容错等。而建立表和表之间关系的最佳方式就是Join操作。对于Spark来说有3中Join的实现,每种Join对应着不同的应用场景:BroadcastHashJoin:适合一张较小的表和一张大表进行joinShuffleHash