一、前言
SQL JOIN是軟件開發(fā)者的必會(huì)知識(shí)點(diǎn),這些JOIN有什么區(qū)別和聯(lián)系呢,本文來(lái)一一剖析。
要了解SQL,其實(shí)我們需要了解下關(guān)系代數(shù)。為什么這么說(shuō)呢?
數(shù)據(jù)庫(kù)系統(tǒng)合并數(shù)據(jù)的原理其實(shí)是基于關(guān)系代數(shù)。SQL 語(yǔ)言是在關(guān)系代數(shù)上的一層封裝,目的是方便程序員使用。關(guān)系代數(shù)是 SQL 語(yǔ)言的基礎(chǔ)。
二、什么是關(guān)系代數(shù)
1、關(guān)系代數(shù):
關(guān)系代數(shù)是由E.F.Codd于1970年提出的,它是合并數(shù)據(jù)集合的理論基礎(chǔ)。
關(guān)系代數(shù)的操作接受一個(gè)或多個(gè)關(guān)系作為輸入,再輸出一個(gè)新的關(guān)系,不同的關(guān)系操作可以進(jìn)行相互的組合。例如可以先進(jìn)行選擇操作再進(jìn)行投影操作,先進(jìn)行自然連接操作再進(jìn)行選擇操作等等。根據(jù)不同的需求需要靈活的組合這些操作。
2、在關(guān)系代數(shù)的形式化語(yǔ)言中:
用表、或者數(shù)據(jù)集合表示關(guān)系或者實(shí)體。
用行表示元組。
用列表示屬性。
3、關(guān)系代數(shù)包含三大類運(yùn)算符:
關(guān)系運(yùn)算符 :選擇、投影、連接、除
集合運(yùn)算符 :并、差、交、笛卡爾積
比較操作符:大于 小于 等于 與 或 非
比較操作符比較簡(jiǎn)單就不介紹了,集合和關(guān)系運(yùn)算符共8個(gè),我們簡(jiǎn)單說(shuō)明:
? 選擇-返回滿足指定條件的行。select
? 投影-從數(shù)據(jù)集合中返回指定的列。
? 連接-在水平方向上合并兩個(gè)表,其方法是:將兩個(gè)表中在共同數(shù)據(jù)項(xiàng)上相互匹配的那些行合并起來(lái)。Join
? 除-返回兩個(gè)數(shù)據(jù)集之間的精確匹配。
? 并-關(guān)系的加法和減法,它可以在行的方向上合并兩個(gè)表中的數(shù)據(jù),就像把一個(gè)表壘在另一個(gè)表之上一樣。
? 交-返回兩個(gè)數(shù)據(jù)集合所共有的行。
? 差-返回只屬于一個(gè)數(shù)據(jù)集合的行。
? 笛卡爾積-是關(guān)系的乘法,它將分別來(lái)自兩個(gè)數(shù)據(jù)集合中的行以所有可能的方式進(jìn)行組合。
此外,作為一種實(shí)現(xiàn)現(xiàn)代關(guān)系代數(shù)運(yùn)算的方法,SQL還提供了:
? 子查詢-類似于連接,但更靈活;在外部查詢中,可以使用表達(dá)式、列表或者數(shù)據(jù)集合的地方都可以使用子查詢的結(jié)果。
本文將主要講述多種類型的連接。
三、連接
3.1 什么是連接JOIN
JOIN子句合并兩個(gè)或多個(gè)表中的行。在臨時(shí)表中創(chuàng)建一組行。
3.2 連接類型
在關(guān)系代數(shù)中,連接運(yùn)算是由一個(gè)笛卡爾積運(yùn)算和一個(gè)選取運(yùn)算構(gòu)成的。首先用笛卡爾積完成對(duì)兩個(gè)數(shù)據(jù)集合的乘運(yùn)算,然后對(duì)生成的結(jié)果集合進(jìn)行選取運(yùn)算,確保只把分別來(lái)自兩個(gè)數(shù)據(jù)集合并且具有重疊部分的行合并在一起。連接的全部意義在于在水平方向上合并兩個(gè)數(shù)據(jù)集合(通常是表),并產(chǎn)生一個(gè)新的結(jié)果集合,其方法是將一個(gè)數(shù)據(jù)源中的行與另一個(gè)數(shù)據(jù)源中和它匹配的行組合成一個(gè)新元組。
SQL提供了多種類型的連接方式,它們之間的區(qū)別在于:從相互交疊的不同數(shù)據(jù)集合中選擇用于連接的行時(shí)所采用的方法不同。
|
連接類型 |
定義 |
|
自身連接 |
|
|
內(nèi)連接 |
只連接匹配的行 |
|
左連接或左外連接 |
包含左邊表的全部行(不管右邊的表中是否存在與它們匹配的行),以及右邊表中全部匹配的行 |
|
右連接或右外連接 |
包含右邊表的全部行(不管左邊的表中是否存在與它們匹配的行),以及左邊表中全部匹配的行 |
|
全外連接 |
包含左、右兩個(gè)表的全部行,不管另外一邊的表中是否存在與它們匹配的行。 |
|
自然連接 |
其結(jié)構(gòu)使得具有相同名稱的關(guān)聯(lián)表的列將僅出現(xiàn)一次 |
|
交叉連接 |
生成笛卡爾積-它不使用任何匹配或者選取條件,而是直接將一個(gè)數(shù)據(jù)源中的每個(gè)行與另一個(gè)數(shù)據(jù)源的每個(gè)行都一一匹配
|
3.2.1 自身連接
自聯(lián)接是表與自身聯(lián)接(一元關(guān)系)的聯(lián)接,特別是當(dāng)表具有引用其自身PRIMARY KEY的FOREIGN KEY時(shí)。例如人力資源數(shù)據(jù)庫(kù)中雇員與老板的關(guān)系。聯(lián)接表本身意味著表的每一行都與自身以及表的其他每一行結(jié)合在一起。自聯(lián)接可以看作是同一表的兩個(gè)副本的聯(lián)接。
例如:SELF JOIN
SELECT *
FROM table_A X,table_A Y
WHERE XA = YA;
3.2.2 內(nèi)連接(Inner Join)
只要各列之間存在匹配,INNER JOIN就會(huì)從兩個(gè)參與表中選擇所有行。SQL INNER JOIN與JOIN子句相同(即inner可以省略),它組合了兩個(gè)或多個(gè)表中的行。
示例:INNER JOIN
SELECT * FROM table_A
INNER JOIN table_B
ON table_A.A = table_B.A;
3.2.3 左外連接(Left Outer Jion)
SQL LEFT JOIN連接兩個(gè)表,并根據(jù)條件獲取行,兩個(gè)表中的行均匹配。
JOIN子句之前的表中還將提供不匹配的行。
示例:LEFT JOIN或LEFT OUTER JOIN
SELECT * FROM table_A
LEFT JOIN table_B
ON table_A.A = table_B.A;
3.2.4 右外連接(Right Outer Jion)
SQL RIGHT JOIN連接兩個(gè)表,并根據(jù)條件獲取行,兩個(gè)表中的行均匹配。不匹配的行也可以從JOIN子句后面編寫的表中獲得。
示例:RIGHT JOIN或RIGHT OUTER JOIN
SELECT * FROM table_A
RIGHT JOIN table_B
ON table_A.A = table_B.A;
3.2.5 全外連接(Full Outer Join)
合并左右外部聯(lián)接的結(jié)果。返回所有匹配或不匹配的行。在join子句的兩邊都包含表。
說(shuō)明:全外連接返回參與連接的兩個(gè)數(shù)據(jù)集合中的全部數(shù)據(jù),無(wú)論它們是否具有與之相匹配的行。在功能上,它等價(jià)于對(duì)這兩個(gè)數(shù)據(jù)集合分別進(jìn)行左外連接和右外連接,然后再使用消去重復(fù)行的并操作將上述兩個(gè)結(jié)果集合并為一個(gè)結(jié)果集。
在現(xiàn)實(shí)生活中,參照完整性約束可以減少對(duì)于全外連接的使用,一般情況下左外連接就足夠了。在數(shù)據(jù)庫(kù)中沒(méi)有利用清晰、規(guī)范的約束來(lái)防范錯(cuò)誤數(shù)據(jù)情況下,全外連接就變得非常有用了,你可以使用它來(lái)清理數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
示例:FULL OUTER JOIN
SELECT * FROM table_A
FULL OUTER JOIN table_B
ON table_A.A = table_B.A;
3.2.6 交叉(無(wú)限制) 連接(CROSS JOIN)
如果未與CROSS JOIN一起使用WHERE子句,則SQL CROSS JOIN會(huì)產(chǎn)生一個(gè)結(jié)果集,該結(jié)果集是第一個(gè)表中的行數(shù)乘以第二個(gè)表中的行數(shù)。這種結(jié)果稱為笛卡爾積。例如,如果第一個(gè)數(shù)據(jù)源中有5個(gè)行,而第二個(gè)數(shù)據(jù)源中有4個(gè)行,那么在它們之間進(jìn)行交叉連接就會(huì)產(chǎn)生20個(gè)行。如果WHERE子句與CROSS JOIN一起使用,則其功能類似于INNER JOIN。
說(shuō)明:大多數(shù)交叉連接都是由于錯(cuò)誤操作而造成的;但是它們卻非常適合向數(shù)據(jù)庫(kù)中填充例子數(shù)據(jù),或者預(yù)先創(chuàng)建一些空行以便為程序執(zhí)行期間所要填充的數(shù)據(jù)保留空間。
示例:CROSS JOIN
SELECT *
FROM table_A
Cross join table_B;
3.2.7 自然連接(NATURAL JOIN)
SQL NATURAL JOIN是EQUI JOIN的一種,其結(jié)構(gòu)使得具有相同名稱的關(guān)聯(lián)表的列將僅出現(xiàn)一次。關(guān)聯(lián)的表具有一對(duì)或多對(duì)相同名稱的列。這些列必須是相同的數(shù)據(jù)類型。不要在自然連接中使用ON子句。
示例:NATURAL JOIN
SELECT *
FROM table_A
NATURAL JOIN table_B;
四、小結(jié)
1、掌握SQL語(yǔ)言要掌握關(guān)系代數(shù)。關(guān)系代數(shù)的三類運(yùn)算符:關(guān)系運(yùn)算符、集合運(yùn)算符、比較操作符。數(shù)據(jù)庫(kù)系統(tǒng)合并數(shù)據(jù)的原理其實(shí)是基于關(guān)系代數(shù)。SQL 語(yǔ)言是在關(guān)系代數(shù)上的一層封裝。
2、不同join之間的區(qū)別。






