十年網(wǎng)站開發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營維護(hù)+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
本文主要介紹 SQL 標(biāo)準(zhǔn)中定義的各種連接的意義和區(qū)別,例如,交叉連接( CROSS JOIN )、內(nèi)連接( INNER JOIN )、外連接( OUTER JOIN )、自然連接( NATURAL JOIN )等,并結(jié)合例子講解這些連接在 MySQL 中的語法和表現(xiàn)。

創(chuàng)新互聯(lián)建站-成都網(wǎng)站建設(shè)公司,專注成都做網(wǎng)站、成都網(wǎng)站建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站營銷推廣,國際域名空間,虛擬空間,網(wǎng)站托管運(yùn)營有關(guān)企業(yè)網(wǎng)站制作方案、改版、費(fèi)用等問題,請聯(lián)系創(chuàng)新互聯(lián)建站。
從網(wǎng)上的資料看, JOIN 更多翻譯為連接,本文中凡是出現(xiàn)中文“連接”的地方都是指 JOIN 。
本文中用到的所有例子涉及兩張表—— customers 用戶表和 orders 訂單表,其中訂單表中的 cust_id 字段表示用戶的唯一 ID,也就是用戶表的主鍵 cust_id 。兩張表的數(shù)據(jù)如下:
注:兩張表都經(jīng)過了簡化,實(shí)際業(yè)務(wù)中這兩張表肯定還包括其他字段。
英文維基百科 JOIN 詞條 對連接的定義如下:
翻譯過來就是,“連接可以根據(jù)一張(自連接)或多張表中的共同值將這些表的列數(shù)據(jù)合并為一個新的結(jié)果集,標(biāo)準(zhǔn) SQL 定義了五種連接:內(nèi)連接、左外連接、右外連接、全外連接和交叉連接?!?/p>
也就是說,連接是 SQL 標(biāo)準(zhǔn)中定義的一種組合多張表的方式,當(dāng)然一張表自身也可以和自身組合,稱為自連接。連接后得到的結(jié)果集的每一列其實(shí)都來自用于連接的多張表,不同的連接類型只是區(qū)分了這些列具體從哪張表里來,列里填充的是什么數(shù)據(jù)。
其實(shí)英文維基百科的 JOIN 詞條已經(jīng)把各種連接的類型解釋地非常清楚了,非常值得去看一下。
我們來看一下 SQL 標(biāo)準(zhǔn)中定義的各種連接類型,理解各種連接最好的方法就是把需要連接的表想象成集合,并畫出可以反映集合的交與并的情況的圖——韋恩圖,例如下圖就畫出了 SQL 中定義的幾種主要連接。
請先仔細(xì)查看一下圖中的內(nèi)容,你可以從中歸納出幾種連接類型呢?
雖然圖中畫了 7 種集合的交并情況,但是總結(jié)起來,主要是兩種連接類型在起作用——內(nèi)連接( INNER JOIN )和外連接( OUTER JOIN ),其中外連接又分為了左外連接( LEFT OUTER JOIN )、右外連接( RIGHT OUTER JOIN )和全外連接( FULL OUTER JOIN )。
下面先簡單介紹一下 SQL 標(biāo)準(zhǔn)中各種連接的定義,然后在「MySQL 中的連接」一節(jié)再用例子來演示 MySQL 中支持的各種連接。
連接既然是用來合并多張表的,那么要定義一個連接就必須指定需要連接的表,并指定可選的連接條件。例如,一個典型的 SQL 連接語句如下:
我們用表 A 和表 B 指代需要連接的兩張表,經(jīng)過 內(nèi)連接 后得到的結(jié)果集 僅 包含所有滿足 連接條件 的數(shù)據(jù);而經(jīng)過 外連接 后得到的數(shù)據(jù)集 不僅 包含滿足 連接條件 的數(shù)據(jù),還包含其他數(shù)據(jù),具體的差別是:
在上面「SQL 標(biāo)準(zhǔn)定義的主要連接」一圖中并沒有列出交叉連接,交叉連接會對連接的兩張表做笛卡爾積,也就是連接后的數(shù)據(jù)集中的行是由第一張表中的每一行與第二張表中的每一行配對而成的,而不管它們 邏輯上 是否可以搭配在一起。假設(shè)交叉連接的兩張表分別有 m 和 n 行數(shù)據(jù),那么交叉連接后的數(shù)據(jù)集就包含 m 乘以 n 行數(shù)據(jù)。
連接根據(jù)連接的條件不同,又可以區(qū)分為等值連接和非等值連接,「SQL 標(biāo)準(zhǔn)定義的主要連接」圖中畫出的連接的連接條件都是比較兩個字段是否相等,它們都是等值連接。
自然連接是等值連接的一種特殊形式,自然連接會自動選取需要連接的兩張表中字段名相同的 所有 列做相等比較,而不需要再指定連接條件了。
注:以下內(nèi)容全部基于 MySQL 5.7 版本,所有例子只保證在 MySQL 5.7 上是可以正確執(zhí)行的。
MySQL 中支持的連接類型和關(guān)鍵字如下:
上面的表示方法摘自 MySQL 5.7 版本 官方文檔 ,其中 | 表示兩者皆可出現(xiàn), [] 表示的是可選的, {} 表示的是必選的,例如 NATURAL LEFT JOIN 和 NATURAL JOIN 都是合法的。
可以看到,除了全外連接( FULL OUTER JOIN )以外, MySQL 基本支持了 SQL 標(biāo)準(zhǔn)中定義的各種連接。在 MySQL 中全外連接可以通過 UNION 合并的方式做到,當(dāng)然前提是你知道自己為什么需要這么做,具體參見: Full Out Join in MySQL 。
MySQL 語法中還支持一個并不在 SQL 標(biāo)準(zhǔn)中的 STRAIGHT_JOIN ,它在 表現(xiàn)上 和內(nèi)連接或者交叉連接并無區(qū)別,只是一種給 MySQL 優(yōu)化器的一個提示, STRAIGHT_JOIN 提示 MySQL 按照語句中表的順序加載表,只有在你明確清楚 MySQL 服務(wù)器對你的 JOIN 語句做了負(fù)優(yōu)化的時候才可能用到它。
還有一點(diǎn)需要說明的是,根據(jù) 官方文檔 ,在 MySQL 中, JOIN 、 CROSS JOIN 和 INNER JOIN 實(shí)現(xiàn)的功能是一致的,它們在語法上是等價的。從語義上來說, CROSS JOIN 特指無條件的連接(沒有指定 ON 條件的 JOIN 或者沒有指定 WHERE 連接條件的多表 SELECT ), INNER JOIN 特指有條件的連接(指定了 ON 條件的 JOIN 或者指定了 WHERE 連接條件的多表 SELECT )。當(dāng)然,如果你非要寫 ... CROSS JOIN ... ON ... 這樣的語法,也是可以執(zhí)行的,雖然寫著交叉連接,實(shí)際上執(zhí)行的是內(nèi)連接。
下面我們就用例子來看一看 MySQL 中支持的幾種連接的例子。
注:下面的例子都沒有指定 ORDER BY 子句,返回結(jié)果的順序可能會因?yàn)閿?shù)據(jù)插入順序的不同而略有不同。
MySQL 的交叉連接或內(nèi)連接有兩種寫法,一種是使用 JOIN 并用 ON 或者 USING 子句指定連接條件的寫法,一種是普通的 SELECT 多表,并且用 WHERE 子句指定連接的鍵的寫法。
下面的例子是一個交叉連接:
上面的寫法等價于:
當(dāng)然,第二種寫法中如果將 CROSS JOIN 替換成 JOIN 或者 INNER JOIN 也是可以正確執(zhí)行的。上面兩條語句的執(zhí)行結(jié)果如下:
可以看到共返回了 30 行結(jié)果,是兩張表的笛卡爾積。
一個內(nèi)連接的例子如下:
上面的寫法等價于:
在連接條件比較的字段相同的情況下,還可以改用 USING 關(guān)鍵字,上面的寫法等價于:
上面三條語句的返回結(jié)果如下:
可以看到只返回了符合連接條件 customers.cust_id = orders.cust_id 的 6 行結(jié)果,結(jié)果的含義是所有有訂單的用戶和他們的訂單。
左外連接和右外連接的例子如下,其中的 OUTER 關(guān)鍵字可以省略:
其中右外連接的返回與內(nèi)連接的返回是一致的(思考一下為什么),左外連接的返回結(jié)果如下:
可以看到一共返回了 8 行數(shù)據(jù),其中最后兩行數(shù)據(jù)對應(yīng)的 order_id 的值為 NULL ,結(jié)果的含義是所有用戶的訂單,不管這些用戶是否已經(jīng)有訂單存在了。
根據(jù)前面介紹的自然連接的定義,自然連接會自動用參與連接的兩張表中 字段名相同 的列做等值比較,由于例子中的 customers 和 orders 表只有一列名稱相同,我們可以用自然連接的語法寫一個與上面的內(nèi)連接的例子表現(xiàn)行為一樣的語句如下:
可以看到,使用自然連接就不能再用 ON 子句指定連接條件了,因?yàn)檫@完全是多余的。
當(dāng)然,自然連接同樣支持左外連接和右外連接。
下面用一個 customers 表自連接的例子再來說明一下自然連接,語句如下:
因?yàn)槭亲赃B接,因此必須使用 AS 指定別名,否則 MySQL 無法區(qū)分“兩個” customers 表,運(yùn)行的結(jié)果如下:
可以看到結(jié)果集和 customers 表完全一致,大家可以思考一下為什么結(jié)果是這樣的。
文章之前也提到了,MySQL 還支持一種 SQL 標(biāo)準(zhǔn)中沒有定義的“方言”, STRAIGHT_JOIN , STRAIGHT_JOIN 支持帶 ON 子句的內(nèi)連接和不帶 ON 子句的交叉連接,我們來看一個 STRAIGHT_JOIN 版本的內(nèi)連接的例子:
返回結(jié)果與前面內(nèi)連接的例子是一致的,如下:
STRAIGHT_JOIN 的表現(xiàn)和 JOIN 是完全一致的,它只是一種給 MySQL 優(yōu)化器的提示,使得 MySQL 始終按照語句中表的順序讀取表(上面的例子中,MySQL 在執(zhí)行時一定會先讀取 customers 表,再讀取 orders 表),而不會做改變讀取表的順序的優(yōu)化。關(guān)于 MySQL 優(yōu)化器的話題這里不做展開,需要說明的是除非你非常清楚你在做什么,否則不推薦直接使用 STRAIGHT_JOIN 。
你能理解上面的語句是在檢索什么數(shù)據(jù)嗎?
本文主要介紹了 SQL 標(biāo)準(zhǔn)里定義的各種連接的概念,以及 MySQL 中的實(shí)現(xiàn),并通過各種例子來介紹了這些連接的區(qū)別。這些連接不一定都能在實(shí)際開發(fā)中用到,但是做到心中有知識也還是很有必要的。
那么,現(xiàn)在再回憶一下,什么是內(nèi)連接、外連接、自連接、等值連接和自然連接?他們的區(qū)別是什么?
最后,給大家留一個思考題,為什么 MySQL 中沒有左外連接或者右外連接版本的 STRAIGHT_JOIN ?
MySQl遠(yuǎn)程連接數(shù)據(jù)庫有兩種方法,具體如下:
改表法。? 在localhost登入mysql后,更改 "MySql" 數(shù)據(jù)庫中的 "User" 表里的 "Host"選項(xiàng),將"localhost"對應(yīng)的值改為"%",具體代碼如圖所示:
2.授權(quán)法。 若MyUser想要使用mypassword(用戶密碼)從任何主機(jī)連接到mysql服務(wù)器則可以使用此方法,具體步驟如下圖所示。
3.按照上述改法,保存后重啟即可生效。
拓展資料:
數(shù)據(jù)庫(Database)是按照數(shù)據(jù)結(jié)構(gòu)來組織、存儲和管理數(shù)據(jù)的倉庫,它產(chǎn)生于距今六十多年前,隨著信息技術(shù)和市場的發(fā)展,特別是二十世紀(jì)九十年代以后,數(shù)據(jù)管理不再僅僅是存儲和管理數(shù)據(jù),而轉(zhuǎn)變成用戶所需要的各種數(shù)據(jù)管理的方式。
2.數(shù)據(jù)庫有很多種類型,從最簡單的存儲有各種數(shù)據(jù)的表格到能夠進(jìn)行海量數(shù)據(jù)存儲的大型數(shù)據(jù)庫系統(tǒng)都在各個方面得到了廣泛的應(yīng)用。
3.在信息化社會,充分有效地管理和利用各類信息資源,是進(jìn)行科學(xué)研究和決策管理的前提條件數(shù)據(jù)庫技術(shù)是管理信息系統(tǒng)、辦公自動化系統(tǒng)、決策支持系統(tǒng)等各類信息系統(tǒng)的核心部分,是進(jìn)行科學(xué)研究和決策管理的重要技術(shù)手段。
4.數(shù)據(jù)庫是一個單位或是一個應(yīng)用領(lǐng)域的通用數(shù)據(jù)處理系統(tǒng),它存儲的是屬于企業(yè)和事業(yè)部門、團(tuán)體和個人的有關(guān)數(shù)據(jù)的集合。數(shù)據(jù)庫中的數(shù)據(jù)是從全局觀點(diǎn)出發(fā)建立的,按一定的數(shù)據(jù)模型進(jìn)行組織、描述和存儲。
5.其結(jié)構(gòu)基于數(shù)據(jù)間的自然聯(lián)系,從而可提供一切必要的存取路徑,且數(shù)據(jù)不再針對某一應(yīng)用,而是面向全組織,具有整體的結(jié)構(gòu)化特征。
參考資料:數(shù)據(jù)庫_百度百科
一、指代不同
1、JOIN:用于根據(jù)兩個或多個表中的列之間的關(guān)系,從這些表中查詢數(shù)據(jù)。
2、INNER JOIN :組合兩個表中的記錄,只要在公共字段之中有相符的值。
二、特點(diǎn)不同
1、JOIN:每個主鍵的值都是唯一的。這樣做的目的是在不重復(fù)每個表中的所有數(shù)據(jù)的情況下,把表間的數(shù)據(jù)交叉捆綁在一起。
2、INNER JOIN :只要在這兩個表的公共字段之中有相符值,內(nèi)部聯(lián)接將組合兩個表中的記錄。
三、規(guī)定不同
1、JOIN:如果表中有至少一個匹配,則返回行。
2、INNER JOIN :被聯(lián)接的字段的名稱。若不是由數(shù)字構(gòu)成的,則這些字段必須為相同的數(shù)據(jù)類型并包含同類數(shù)據(jù),但無須具有相同的名稱。
參考資料來源:百度百科-INNER JOIN
參考資料來源:百度百科-SQL語句大全
哎。你好淵博啊。
我給你講下幾種鏈接的含義:
1、自然連接 select * a join b on a.id=b.id 含義:用a表的id與b表的id進(jìn)行匹配,匹配上的記錄顯示,而那些匹配不上的,不論是a還是b表的記錄都不顯示。
2、外連接:左連接,右鏈接
左鏈接:select * a left join b on a.id=b.id 含義:用a表的id與b表的id進(jìn)行匹配,匹配上的記錄顯示,而那些匹配不上的,保留a表全部的未匹配記錄,但b表的未匹配記錄不被顯示。
右鏈接:select * a right join b on a.id=b.id 含義:用a表的id與b表的id進(jìn)行匹配,匹配上的記錄顯示,而那些匹配不上的,保留b表未匹配的記錄,但a表的未匹配記錄不被顯示。
3、全關(guān)聯(lián):select * a full join b on a.id=b.id 含義:用a表的id與b表的id進(jìn)行匹配,匹配上的記錄顯示,而那些匹配不上的,保留a表和b表全部的未匹配記錄。
4、笛卡爾積:select * a ,b 含義:就是用a表的每一條記錄都和b表的全部數(shù)據(jù)組合。假設(shè)a表10條,b表100條,會將a表每一條的記錄都和b表的100條進(jìn)行組合,最終生成10*100條記錄。
你看看這個:
natural --
1)兩個關(guān)系(左關(guān)系和友關(guān)系)中所有具有相同的名稱的屬性的值要相等。
2)natural 總是出現(xiàn)在 join語句前面
3)natural的結(jié)果關(guān)系中,相同名稱的屬性只會出現(xiàn)一次
4)natural的結(jié)果關(guān)系中,屬性的排列順序總是按照左關(guān)系優(yōu)先的原則。
5) MySQL中,natural join不能使用on指定其他查詢條件
on--
1)on 用在join語句后面
2)on 后面采用關(guān)系1.屬性a=關(guān)系2.屬性b 的謂詞語法
連接分類
關(guān)系間的連接分為內(nèi)連接(inner join)和外連接(outer join)。
外連接又可分為:left outer join,right outer join和full outer join。
內(nèi)連接計(jì)算方法:
如果不加條件將會產(chǎn)生笛卡爾積;
如果有連接條件,按照下一節(jié)"連接條件"的規(guī)則進(jìn)行運(yùn)算,符合條件的元組放入結(jié)果關(guān)系中。
left outer join 計(jì)算過程:
1)計(jì)算相同連接條件下的內(nèi)連接,將符合條件的元組放入結(jié)果關(guān)系中;
2)如果左關(guān)系中有元組不符合條件,將之放入結(jié)果關(guān)系中,余下的用NULL補(bǔ)足
right outer join 計(jì)算過程:
1)計(jì)算相同連接條件下的內(nèi)連接,將符合條件的元組放入結(jié)果關(guān)系中;
2)如果右關(guān)系中有元組不符合條件,將之放入結(jié)果關(guān)系中,余下的用NULL補(bǔ)足
full outer join
1)計(jì)算相同連接條件下的內(nèi)連接,將符合條件的元組放入結(jié)果關(guān)系中;
2)如果左、右關(guān)系中有元組不符合條件,將之放入結(jié)果關(guān)系中,余下的用NULL補(bǔ)足
as用來修改連接后結(jié)果關(guān)系的關(guān)系名稱以及屬性名稱。
連接條件
關(guān)系之間的連接是可以有條件的,外連接必須要加條件,內(nèi)連接如果不加條件將會產(chǎn)生笛卡爾積。
有哪些連接條件呢?
natural --
1)兩個關(guān)系(左關(guān)系和友關(guān)系)中所有具有相同的名稱的屬性的值要相等。
2)natural 總是出現(xiàn)在 join語句前面
3)natural的結(jié)果關(guān)系中,相同名稱的屬性只會出現(xiàn)一次
4)natural的結(jié)果關(guān)系中,屬性的排列順序總是按照左關(guān)系優(yōu)先的原則。
5) MySQL中,natural join不能使用on指定其他查詢條件
on--
1)on 用在join語句后面
2)on 后面采用關(guān)系1.屬性a=關(guān)系2.屬性b 的謂詞語法
using--
1)和natural類似,只是顯式指定了屬性名稱
2)如果using也指定了所有相同名稱的屬性,那么和natural相同
MySQL
MySQL中,natural join和 left outer join不能在同時使用,可以先將natural join語句做成一個view,然后再使用left outer join
join 默認(rèn)為inner join
多表查詢
SELECT * FROM a,b WHERE a.val = b.val;
連接查詢
SELECT * FROM a LEFT JOIN b ON a.val = b.val;
重點(diǎn):其實(shí)兩種都是連接查詢
多表查詢即自然連接查詢,如下
SELECT * FROM a join b WHERE a.val = b.val;
自然連接查詢:默認(rèn)使用主鍵進(jìn)行連接,且不能改變(即不需要on關(guān)鍵字),可通過where子句進(jìn)行條件篩選,這也是和其他連接查詢最大的不同