來(lái)自MySQL的學(xué)習(xí)筆記,寫(xiě)的不對(duì)的地方大家多多指教哦
專(zhuān)注于為中小企業(yè)提供網(wǎng)站制作、網(wǎng)站設(shè)計(jì)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)平昌免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了近千家企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。
什么是外鍵?
假設(shè)有 2 個(gè)表,分別是表 A 和表 B,它們通過(guò)一個(gè)公共字段“id”發(fā)生關(guān)聯(lián)關(guān)系,我們把這個(gè)關(guān)聯(lián)關(guān)系叫做 R。如果“id”在表 A 中是主鍵,那么,表 A 就是這個(gè)關(guān)系 R 中的主表。相應(yīng)的,表 B 就是這個(gè)關(guān)系中的從表,表 B 中的“id”,就是表 B 用來(lái)引用表 A 中數(shù)據(jù)的,叫外鍵。所以,外鍵就是從表中用來(lái)引用主表中數(shù)據(jù)的那個(gè)公共字段。
語(yǔ)法結(jié)構(gòu):
在創(chuàng)建表時(shí)添加外鍵約束:
在修改表時(shí)定義外鍵約束:
例子1:創(chuàng)建表時(shí)添加外鍵約束
首先創(chuàng)建主表:importhead
創(chuàng)建從表:test_mysql.importdetails
查詢(xún)外鍵約束的相關(guān)信息:
查詢(xún)結(jié)果為:
例子2:修改表時(shí)定義外鍵約束
修改表時(shí)定義從表test_mysql.importdetails的外鍵約束
刪除外鍵約束使用DROP,語(yǔ)法結(jié)構(gòu)為:
例子:刪除從表test_mysql.importdetails的外鍵約束
在 MySQL 中,有 2 種類(lèi)型的連接,分別是內(nèi)連接(INNER JOIN)和外連接(OUTER JOIN)。
在 MySQL 里面,關(guān)鍵字 JOIN、INNER JOIN、CROSS JOIN 的含義是一樣的,都表示內(nèi)連接。我們可以通過(guò) JOIN 把兩個(gè)表關(guān)聯(lián)起來(lái),來(lái)查詢(xún)兩個(gè)表中的數(shù)據(jù)。
例子:有一張銷(xiāo)售表,如下圖:
有一張會(huì)員信息表,如下圖:
通過(guò)內(nèi)連接,查詢(xún)會(huì)員的銷(xiāo)售記錄:
運(yùn)行語(yǔ)句,結(jié)果如下:
根據(jù)上面的結(jié)果,其實(shí)可以得知:內(nèi)連接查詢(xún)到結(jié)果集為兩個(gè)表的交集部分。
跟內(nèi)連接只返回符合連接條件的記錄不同的是,外連接還可以返回表中的所有記錄,它包括兩類(lèi),分別是左連接和右連接。
例子1:左外連接
如果需要查詢(xún)所有銷(xiāo)售記錄,則可以使用左外連接
運(yùn)行語(yǔ)句,結(jié)果為:
從上面的結(jié)果可以得知,LEFT JOIN左邊的表會(huì)返回全部記錄,而右邊的表只返回符合連接條件的記錄
例子2:右外連接:
運(yùn)行語(yǔ)句,結(jié)果為:
從上面的結(jié)果可以得知,RIGHT JOIN右邊的表會(huì)返回全部記錄,而左邊的表只返回符合連接條件的記錄
學(xué)生student表:
課程course表:
交叉連接:
結(jié)果為兩張表的笛卡爾積:
內(nèi)連接(inner join ,inner 可以省略)
顯示內(nèi)連接和隱示內(nèi)連接獲得的查詢(xún)結(jié)果是一樣的,都是A表和B表的交集(例:A.id = B.id),但是只能查到有關(guān)系的信息,如果A表的一條數(shù)據(jù)的與B表關(guān)聯(lián)的字段沒(méi)有對(duì)應(yīng)的信息(如:A.id = null),即:這條數(shù)據(jù)在B表中沒(méi)有對(duì)應(yīng)的信息,則無(wú)法獲得。
外連接(outer join,outer可以省略)
左外連接獲得的查詢(xún)結(jié)果是左邊的表A的全部信息和A,B兩張表的交集,左邊A表的全部包含A表中在B表中沒(méi)有對(duì)應(yīng)關(guān)系的信息。
右外連接獲得的查詢(xún)結(jié)果是右邊的表B的全部信息和A,B兩張表的交集,右邊B表的全部包含B表中在A表中沒(méi)有對(duì)應(yīng)關(guān)系的信息。
左連接:返回包括左表中的所有記錄和右表中聯(lián)結(jié)字段相等的記錄;
右連接:返回包括右表中的所有記錄和左表中聯(lián)結(jié)字段相等的記錄;
全連接:返回兩個(gè)連接表的所有記錄;mysql沒(méi)有全連接
內(nèi)連接:返回兩個(gè)連接表連接字段相同的記錄;
union:對(duì)兩個(gè)結(jié)果集進(jìn)行并集,并去重,當(dāng)交換兩個(gè)select語(yǔ)句順序后,最終結(jié)果與不交換時(shí)無(wú)區(qū)別;
union all:對(duì)兩個(gè)結(jié)果集進(jìn)行并集,不去重,當(dāng)交換兩個(gè)select語(yǔ)句順序后,最終結(jié)果與不交換時(shí)有區(qū)別;
舉個(gè)例子 有一個(gè)學(xué)生表 班級(jí) 姓名 一個(gè)成績(jī)表 姓名 成績(jī) 我們需要返回X班的所有學(xué)生的成績(jī),但是班上有人缺考,也就是成績(jī)表里沒(méi)有姓名,我們先用on得到的就是有考試成績(jī)的名字,通過(guò)外連接,我們就可以得到全班人的名字以及成績(jī)。
本文主要介紹 SQL 標(biāo)準(zhǔn)中定義的各種連接的意義和區(qū)別,例如,交叉連接( CROSS JOIN )、內(nèi)連接( INNER JOIN )、外連接( OUTER JOIN )、自然連接( NATURAL JOIN )等,并結(jié)合例子講解這些連接在 MySQL 中的語(yǔ)法和表現(xiàn)。
從網(wǎng)上的資料看, JOIN 更多翻譯為連接,本文中凡是出現(xiàn)中文“連接”的地方都是指 JOIN 。
本文中用到的所有例子涉及兩張表—— customers 用戶(hù)表和 orders 訂單表,其中訂單表中的 cust_id 字段表示用戶(hù)的唯一 ID,也就是用戶(hù)表的主鍵 cust_id 。兩張表的數(shù)據(jù)如下:
注:兩張表都經(jīng)過(guò)了簡(jiǎn)化,實(shí)際業(yè)務(wù)中這兩張表肯定還包括其他字段。
英文維基百科 JOIN 詞條 對(duì)連接的定義如下:
翻譯過(guò)來(lái)就是,“連接可以根據(jù)一張(自連接)或多張表中的共同值將這些表的列數(shù)據(jù)合并為一個(gè)新的結(jié)果集,標(biāo)準(zhǔn) SQL 定義了五種連接:內(nèi)連接、左外連接、右外連接、全外連接和交叉連接。”
也就是說(shuō),連接是 SQL 標(biāo)準(zhǔn)中定義的一種組合多張表的方式,當(dāng)然一張表自身也可以和自身組合,稱(chēng)為自連接。連接后得到的結(jié)果集的每一列其實(shí)都來(lái)自用于連接的多張表,不同的連接類(lèi)型只是區(qū)分了這些列具體從哪張表里來(lái),列里填充的是什么數(shù)據(jù)。
其實(shí)英文維基百科的 JOIN 詞條已經(jīng)把各種連接的類(lèi)型解釋地非常清楚了,非常值得去看一下。
我們來(lái)看一下 SQL 標(biāo)準(zhǔn)中定義的各種連接類(lèi)型,理解各種連接最好的方法就是把需要連接的表想象成集合,并畫(huà)出可以反映集合的交與并的情況的圖——韋恩圖,例如下圖就畫(huà)出了 SQL 中定義的幾種主要連接。
請(qǐng)先仔細(xì)查看一下圖中的內(nèi)容,你可以從中歸納出幾種連接類(lèi)型呢?
雖然圖中畫(huà)了 7 種集合的交并情況,但是總結(jié)起來(lái),主要是兩種連接類(lèi)型在起作用——內(nèi)連接( INNER JOIN )和外連接( OUTER JOIN ),其中外連接又分為了左外連接( LEFT OUTER JOIN )、右外連接( RIGHT OUTER JOIN )和全外連接( FULL OUTER JOIN )。
下面先簡(jiǎn)單介紹一下 SQL 標(biāo)準(zhǔn)中各種連接的定義,然后在「MySQL 中的連接」一節(jié)再用例子來(lái)演示 MySQL 中支持的各種連接。
連接既然是用來(lái)合并多張表的,那么要定義一個(gè)連接就必須指定需要連接的表,并指定可選的連接條件。例如,一個(gè)典型的 SQL 連接語(yǔ)句如下:
我們用表 A 和表 B 指代需要連接的兩張表,經(jīng)過(guò) 內(nèi)連接 后得到的結(jié)果集 僅 包含所有滿(mǎn)足 連接條件 的數(shù)據(jù);而經(jīng)過(guò) 外連接 后得到的數(shù)據(jù)集 不僅 包含滿(mǎn)足 連接條件 的數(shù)據(jù),還包含其他數(shù)據(jù),具體的差別是:
在上面「SQL 標(biāo)準(zhǔn)定義的主要連接」一圖中并沒(méi)有列出交叉連接,交叉連接會(huì)對(duì)連接的兩張表做笛卡爾積,也就是連接后的數(shù)據(jù)集中的行是由第一張表中的每一行與第二張表中的每一行配對(duì)而成的,而不管它們 邏輯上 是否可以搭配在一起。假設(shè)交叉連接的兩張表分別有 m 和 n 行數(shù)據(jù),那么交叉連接后的數(shù)據(jù)集就包含 m 乘以 n 行數(shù)據(jù)。
連接根據(jù)連接的條件不同,又可以區(qū)分為等值連接和非等值連接,「SQL 標(biāo)準(zhǔn)定義的主要連接」圖中畫(huà)出的連接的連接條件都是比較兩個(gè)字段是否相等,它們都是等值連接。
自然連接是等值連接的一種特殊形式,自然連接會(huì)自動(dòng)選取需要連接的兩張表中字段名相同的 所有 列做相等比較,而不需要再指定連接條件了。
注:以下內(nèi)容全部基于 MySQL 5.7 版本,所有例子只保證在 MySQL 5.7 上是可以正確執(zhí)行的。
MySQL 中支持的連接類(lèi)型和關(guān)鍵字如下:
上面的表示方法摘自 MySQL 5.7 版本 官方文檔 ,其中 | 表示兩者皆可出現(xiàn), [] 表示的是可選的, {} 表示的是必選的,例如 NATURAL LEFT JOIN 和 NATURAL JOIN 都是合法的。
可以看到,除了全外連接( FULL OUTER JOIN )以外, MySQL 基本支持了 SQL 標(biāo)準(zhǔn)中定義的各種連接。在 MySQL 中全外連接可以通過(guò) UNION 合并的方式做到,當(dāng)然前提是你知道自己為什么需要這么做,具體參見(jiàn): Full Out Join in MySQL 。
MySQL 語(yǔ)法中還支持一個(gè)并不在 SQL 標(biāo)準(zhǔn)中的 STRAIGHT_JOIN ,它在 表現(xiàn)上 和內(nèi)連接或者交叉連接并無(wú)區(qū)別,只是一種給 MySQL 優(yōu)化器的一個(gè)提示, STRAIGHT_JOIN 提示 MySQL 按照語(yǔ)句中表的順序加載表,只有在你明確清楚 MySQL 服務(wù)器對(duì)你的 JOIN 語(yǔ)句做了負(fù)優(yōu)化的時(shí)候才可能用到它。
還有一點(diǎn)需要說(shuō)明的是,根據(jù) 官方文檔 ,在 MySQL 中, JOIN 、 CROSS JOIN 和 INNER JOIN 實(shí)現(xiàn)的功能是一致的,它們?cè)谡Z(yǔ)法上是等價(jià)的。從語(yǔ)義上來(lái)說(shuō), CROSS JOIN 特指無(wú)條件的連接(沒(méi)有指定 ON 條件的 JOIN 或者沒(méi)有指定 WHERE 連接條件的多表 SELECT ), INNER JOIN 特指有條件的連接(指定了 ON 條件的 JOIN 或者指定了 WHERE 連接條件的多表 SELECT )。當(dāng)然,如果你非要寫(xiě) ... CROSS JOIN ... ON ... 這樣的語(yǔ)法,也是可以執(zhí)行的,雖然寫(xiě)著交叉連接,實(shí)際上執(zhí)行的是內(nèi)連接。
下面我們就用例子來(lái)看一看 MySQL 中支持的幾種連接的例子。
注:下面的例子都沒(méi)有指定 ORDER BY 子句,返回結(jié)果的順序可能會(huì)因?yàn)閿?shù)據(jù)插入順序的不同而略有不同。
MySQL 的交叉連接或內(nèi)連接有兩種寫(xiě)法,一種是使用 JOIN 并用 ON 或者 USING 子句指定連接條件的寫(xiě)法,一種是普通的 SELECT 多表,并且用 WHERE 子句指定連接的鍵的寫(xiě)法。
下面的例子是一個(gè)交叉連接:
上面的寫(xiě)法等價(jià)于:
當(dāng)然,第二種寫(xiě)法中如果將 CROSS JOIN 替換成 JOIN 或者 INNER JOIN 也是可以正確執(zhí)行的。上面兩條語(yǔ)句的執(zhí)行結(jié)果如下:
可以看到共返回了 30 行結(jié)果,是兩張表的笛卡爾積。
一個(gè)內(nèi)連接的例子如下:
上面的寫(xiě)法等價(jià)于:
在連接條件比較的字段相同的情況下,還可以改用 USING 關(guān)鍵字,上面的寫(xiě)法等價(jià)于:
上面三條語(yǔ)句的返回結(jié)果如下:
可以看到只返回了符合連接條件 customers.cust_id = orders.cust_id 的 6 行結(jié)果,結(jié)果的含義是所有有訂單的用戶(hù)和他們的訂單。
左外連接和右外連接的例子如下,其中的 OUTER 關(guān)鍵字可以省略:
其中右外連接的返回與內(nèi)連接的返回是一致的(思考一下為什么),左外連接的返回結(jié)果如下:
可以看到一共返回了 8 行數(shù)據(jù),其中最后兩行數(shù)據(jù)對(duì)應(yīng)的 order_id 的值為 NULL ,結(jié)果的含義是所有用戶(hù)的訂單,不管這些用戶(hù)是否已經(jīng)有訂單存在了。
根據(jù)前面介紹的自然連接的定義,自然連接會(huì)自動(dòng)用參與連接的兩張表中 字段名相同 的列做等值比較,由于例子中的 customers 和 orders 表只有一列名稱(chēng)相同,我們可以用自然連接的語(yǔ)法寫(xiě)一個(gè)與上面的內(nèi)連接的例子表現(xiàn)行為一樣的語(yǔ)句如下:
可以看到,使用自然連接就不能再用 ON 子句指定連接條件了,因?yàn)檫@完全是多余的。
當(dāng)然,自然連接同樣支持左外連接和右外連接。
下面用一個(gè) customers 表自連接的例子再來(lái)說(shuō)明一下自然連接,語(yǔ)句如下:
因?yàn)槭亲赃B接,因此必須使用 AS 指定別名,否則 MySQL 無(wú)法區(qū)分“兩個(gè)” customers 表,運(yùn)行的結(jié)果如下:
可以看到結(jié)果集和 customers 表完全一致,大家可以思考一下為什么結(jié)果是這樣的。
文章之前也提到了,MySQL 還支持一種 SQL 標(biāo)準(zhǔn)中沒(méi)有定義的“方言”, STRAIGHT_JOIN , STRAIGHT_JOIN 支持帶 ON 子句的內(nèi)連接和不帶 ON 子句的交叉連接,我們來(lái)看一個(gè) STRAIGHT_JOIN 版本的內(nèi)連接的例子:
返回結(jié)果與前面內(nèi)連接的例子是一致的,如下:
STRAIGHT_JOIN 的表現(xiàn)和 JOIN 是完全一致的,它只是一種給 MySQL 優(yōu)化器的提示,使得 MySQL 始終按照語(yǔ)句中表的順序讀取表(上面的例子中,MySQL 在執(zhí)行時(shí)一定會(huì)先讀取 customers 表,再讀取 orders 表),而不會(huì)做改變讀取表的順序的優(yōu)化。關(guān)于 MySQL 優(yōu)化器的話(huà)題這里不做展開(kāi),需要說(shuō)明的是除非你非常清楚你在做什么,否則不推薦直接使用 STRAIGHT_JOIN 。
你能理解上面的語(yǔ)句是在檢索什么數(shù)據(jù)嗎?
本文主要介紹了 SQL 標(biāo)準(zhǔn)里定義的各種連接的概念,以及 MySQL 中的實(shí)現(xiàn),并通過(guò)各種例子來(lái)介紹了這些連接的區(qū)別。這些連接不一定都能在實(shí)際開(kāi)發(fā)中用到,但是做到心中有知識(shí)也還是很有必要的。
那么,現(xiàn)在再回憶一下,什么是內(nèi)連接、外連接、自連接、等值連接和自然連接?他們的區(qū)別是什么?
最后,給大家留一個(gè)思考題,為什么 MySQL 中沒(méi)有左外連接或者右外連接版本的 STRAIGHT_JOIN ?
本文標(biāo)題:mysql內(nèi)連接怎么用 mysql內(nèi)連接用法
文章轉(zhuǎn)載:http://redsoil1982.com.cn/article42/dophihc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)、全網(wǎng)營(yíng)銷(xiāo)推廣、虛擬主機(jī)、響應(yīng)式網(wǎng)站、網(wǎng)站內(nèi)鏈、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容