SQL JOIN 簡單介紹

前言

  本文仍是秉持以前一向的寫做風格,以簡單易懂的示例幫助你們瞭解各類join的區別。mysql

 爲何須要join

  爲何須要join?join中文意思爲鏈接,鏈接意味着關聯即將一個表和多個表之間關聯起來。在處理數據庫表的時候,咱們常常會發現,須要從多個表中獲取信息,將多個表的多個字段數據組裝起來再返回給調用者。因此join的前提是這些表之間必須有關聯字段。sql

 join的分類

  join分爲兩種,inner join和outer join,其中outer join分爲三種,left outer join, right outer join, full outer join,另外left outer join又簡稱爲left join即你們所熟知的左鏈接。數據庫

 各類join的區別

  在介紹各類join的區別以前,咱們先來看一個簡單的示例:spa

  場景描述:

  互聯網時代,你們都喜歡在網上購物,尤爲是淘寶和京東,因此咱們選擇的場景也是你們熟悉的網上購物。這是一個關於一我的和他在商城買了什麼商品的一個故事;blog

  針對上述需求,咱們創建了兩張表,tb_person和tb_order,其中tb_person是關於這我的的描述,tb_order是關於他購買的商品的一個描述。rem

  咱們的表結構很簡單,tb_person只須要知道這我的是誰就能夠了,因此只有三個字段id,firstname(名)和lastname(姓),一樣tb_order也很簡單,咱們只要知道誰買了什麼商品,因此只須要3個字段,分別是oid, oname(商品名稱), pid(購買者編號)。get

  tb_person:it

+-----------+-------------+------+-----+---------+----------------+
| 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:io

+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| oid   | int(11)     | NO   | PRI | NULL    | auto_increment |
| oname | varchar(50) | YES  |     | NULL    |                |
| pid   | int(11)     | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+

  接下來,咱們向上述兩張表中寫入一些示例數據:table

  data in tb_person:

+-----+-----------+----------+
| pid | firstname | lastname |
+-----+-----------+----------+
|   1 | andy      | chen     |
|   2 | irri      | wan      |
|   3 | abby      | sun      |
+-----+-----------+----------+

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

  data in tb_order:

+-----+----------+------+
| 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兩張表中同時存在;

MariaDB [demo]> SELECT p.pid, p.firstname, o.oname
    -> FROM tb_person p
    -> INNER JOIN tb_order o
    -> ON p.pid=o.pid;
+-----+-----------+-------+
| 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中沒有購買任何商品的用戶集。

MariaDB [demo]> SELECT p.pid, p.firstname, o.oname
    -> FROM tb_person p
    -> LEFT JOIN tb_order o
    -> ON p.pid=o.pid;
+-----+-----------+-------+
| 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表。

MariaDB [demo]> SELECT p.pid, p.firstname, o.oname
    -> FROM tb_person p
    -> RIGHT JOIN tb_order o
    -> ON p.pid=o.pid;
+------+-----------+----------+
| 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的結果。

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;
+------+-----------+----------+
| 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文件

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);
相關文章
相關標籤/搜索