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:
+-----------+-------------+------+-----+---------+----------------+ | 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:
+-------+-------------+------+-----+---------+----------------+ | 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:
+-----+-----------+----------+ | 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兩張表,我們可以看到有三種情形:
-
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兩張表中同時存在;
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);
相關文章
- ZT:簡單介紹join,outer-join,semi-join,anti-join的區別
- SQL | JOIN 型別使用介紹SQL型別
- SVG簡單介紹SVG
- HTML簡單介紹HTML
- ActiveMQ簡單介紹MQ
- HTML 簡單介紹HTML
- JavaScript 簡單介紹JavaScript
- CSS 簡單介紹CSS
- SCSS 簡單介紹CSS
- UICollectionView 簡單介紹UIView
- css簡單介紹CSS
- 簡單介紹SQL中ISNULL函式使用方法SQLNull函式
- 一個left join SQL 簡單優化分析SQL優化
- RPC簡單介紹RPC
- Webpack 的簡單介紹Web
- spark簡單介紹(一)Spark
- Flutter key簡單介紹Flutter
- Python簡單介紹Python
- <svg>元素簡單介紹SVG
- Git_簡單介紹Git
- JSON簡單介紹JSON
- 簡單介紹克隆 JavaScriptJavaScript
- 簡單介紹 ldd 命令
- javascript物件簡單介紹JavaScript物件
- CSS OOCSS簡單介紹CSS
- CSS SMACSS簡單介紹CSSMac
- CSS BEM簡單介紹CSS
- javascript this指向簡單介紹JavaScript
- javascript加密簡單介紹JavaScript加密
- nodejs簡單介紹NodeJS
- Promise的簡單介紹Promise
- CFRunloopObserverRef 的簡單介紹OOPServer
- oracle lob 簡單介紹Oracle
- Oracle鎖簡單介紹Oracle
- ORACLE 鎖簡單介紹Oracle
- Oracle10g SQL tune adviser簡單介紹OracleSQL
- 資料庫介紹--認識簡單的SQL語句資料庫SQL
- 簡單介紹JavaScript閉包JavaScript