MySQL的三條JOIN子句使用指南
譯文【51CTO.com快譯】眾所周知,關(guān)系型數(shù)據(jù)庫(kù)中的每張表都包含了唯一或通用的數(shù)據(jù),而且各個(gè)表之間都存在著邏輯上的聯(lián)系。例如,相同的列名和數(shù)據(jù)類型,通常會(huì)被保存在作為公共值鏈接的表中。因此,我們?cè)谶M(jìn)行單個(gè)SQL查詢時(shí),JOIN語(yǔ)句往往被用于從共享著公共字段的多張表中,連接并獲取數(shù)據(jù)。特別是在MySQL中,JOIN被用于聚合那些來(lái)自多張表的數(shù)據(jù),并將它們整合為單個(gè)輸出結(jié)果。而且,我們可以在SELECT、UPDATE和DELETE命令中,使用到JOIN。
JOIN入門
MySQL的JOIN類型能夠指明在查詢中,兩個(gè)表是如何鏈接的。其中INNER JOIN、OUTER JOIN和CROSS JOIN都是被MySQL支持的三種JOIN子句。而LEFT JOIN和RIGHT JOIN則是兩種不同類型的OUTER JOIN。為了更加直觀地展示該如何使用JOIN,我們首先需要通過(guò)如下方式,創(chuàng)建一個(gè)新結(jié)構(gòu)模式(schema),以便為后續(xù)的操作提供數(shù)據(jù)示例。
MySQL
- CREATE TABLE Users (
- UserID INT,
- UserName VARCHAR(255),
- Password VARCHAR(255),
- isActive BOOLEAN
- );
- CREATE TABLE Userprofile (
- ProfileID INT,
- LastName VARCHAR(255),
- FirstName VARCHAR(255),
- Email VARCHAR(255),
- Phone VARCHAR(255)
- );
接下來(lái),我們要做的便是向其中插入一些數(shù)據(jù)。如下面語(yǔ)句所示,您可以根據(jù)自己的偏好,在表中插入任意數(shù)量的用戶。
MySQL
- INSERT INTO Users
- (UserID, UserName,Password, isActive)
- VALUES
- (1,'krofax','krofax1234', TRUE);
- INSERT INTO userprofile
- (profileid, lastname, firstname, email, phone)
- VALUES
- (1,'Ada', 'George', 'adageorge@gmail.com','1290003456');
MySQL INNER JOIN子句
我們可以使用INNER JOIN去檢索各種常見(jiàn)的匹配性記錄。例如,INNER JOIN子句可以通過(guò)檢索表A和表B中的記錄,為需要滿足某種連接要求而篩選記錄。這也是最常用的JOIN類型。下面的維恩圖可以協(xié)助您更好地理解INNER JOIN。
以下是基于MySQL語(yǔ)法的INNER JOIN:
- SELECT
- COLUMNS
- FROM
- tableA
- INNER JOINtableB
- ON tableA.column = tableB.column;
MySQL外部連接
與INNER JOIN相比,OUTER JOIN會(huì)生成不匹配(non-matching)的記錄,以及匹配的數(shù)據(jù)行。也就是說(shuō),如果連接表中的數(shù)據(jù)行并不匹配的話,則會(huì)顯示NULL值。如前所述,MySQL有兩種不同形式的OUTER JOIN,它們分別是:MySQL LEFT JOIN和MySQL RIGHT JOIN。下面,讓我們來(lái)詳細(xì)地了解它們之間的區(qū)別。
MySQL LEFT JOIN子句
LEFT JOIN允許您從表A和表B中,獲取滿足連接條件的所有條目。而且,對(duì)于表A中不符合條件的記錄,將顯示為NULL值。下面的維恩圖可以協(xié)助您更好地理解LEFT JOIN。
以下是基于MySQL語(yǔ)法的LEFT JOIN子句:
MySQL
- COLUMNS
- tableA
- JOINtableB
- ON tableA.column = tableB.column;
如上圖所示:LEFT JOIN關(guān)鍵字會(huì)返回那些匹配Customers表,而在Orders表中沒(méi)有匹配項(xiàng)的所有記錄。
MySQL RIGHT JOIN子句
而RIGHT JOIN則允許用戶獲取表B中的所有條目,以及滿足連接條件在表A中的條目。也就是說(shuō),表B中不符合條件的記錄會(huì)被顯示為NULL值。下面的維恩圖可以協(xié)助您更好地理解RIGHT JOIN。
以下是基于MySQL語(yǔ)法的RIGHT JOIN子句:
MySQL
- SELECT
- COLUMNS
- FROM
- tableA
- RIGHTJOINtableB
- ON tableA.column = tableB.column;
如上圖所示:該RIGHT JOIN關(guān)鍵字返回那些匹配Employees表,而在Orders表中沒(méi)有匹配項(xiàng)的所有記錄。
MySQL CROSS JOIN子句
MySQL CROSS JOIN通常被稱為笛卡爾連接(cartesian join)。它返回每個(gè)表中所有可能性數(shù)據(jù)行的組合。也就是說(shuō),如果不提供額外的條件,那么可將表A的每一行與表B中的所有行相乘,以得到結(jié)果集。下面的維恩圖可以協(xié)助您更好地理解CROSS JOIN。
那么我們什么時(shí)候會(huì)需要用到這種JOIN呢?假設(shè)您接到一個(gè)任務(wù):查找某個(gè)產(chǎn)品和顏色的所有可能性組合。那么CROSS JOIN在此時(shí)就能夠派上用場(chǎng)了。不過(guò),值得注意的是,CROSS JOIN可能會(huì)產(chǎn)生相當(dāng)大的結(jié)果集!
以下是基于MySQL語(yǔ)法的CROSS JOIN子句:
MySQL
- SELECT
- COLUMNS
- FROM
- tableA
- CROSSJOINtableB;
JOIN的技巧
總的說(shuō)來(lái),在MySQL中,JOIN能夠方便您執(zhí)行單個(gè)JOIN查詢,而省去了許多個(gè)簡(jiǎn)單的查詢。因此,它能夠帶來(lái)更快的速度、更低的服務(wù)器開(kāi)銷、以及更少的MySQL與應(yīng)用之間的數(shù)據(jù)傳輸。與SQL Server不同,MySQL雖然沒(méi)有用于FULL OUTER JOIN的獨(dú)特JOIN類型,但是您可以通過(guò)LEFT OUTER JOIN和RIGHT OUTER JOIN(請(qǐng)參照如下語(yǔ)句)的組合,以獲得與FULL OUTER JOIN相同的輸出效果。
MySQL
- SELECT
- *
- FROM
- tableA
- LEFTJOINtableB
- ON tableA.id = tableB.id
- UNION
- SELECT
- *
- FROM
- tableA
- RIGHTJOINtableB
- ON tableA.id = tableB.id
此外,使用MySQL JOIN,您還可以順利地連接上述兩張表。
MySQL
- SELECT
- *
- FROM
- tableA
- LEFTJOINtableB
- ON tableA.id = tableB.id
- LEFTJOINtableC
- ON tableC.id = tableA.id;
JOINS的實(shí)用性
- 更快的速度。在單個(gè)查詢中,JOINS允許您從兩個(gè)或多個(gè)鏈接的數(shù)據(jù)庫(kù)表中,獲取數(shù)據(jù)。顯然,這比通過(guò)逐個(gè)運(yùn)行查詢,以獲得相同的結(jié)果,要更加節(jié)省時(shí)間。
- MySQL的效率更高。由于連接是通過(guò)索引來(lái)執(zhí)行的,因此JOINS會(huì)讓MySQL具有更好的性能。
- 降低了服務(wù)器的負(fù)載。畢竟JOINS的單次查詢執(zhí)行,能夠讓服務(wù)器更快地輸出結(jié)果。
為了能夠在日常工作中靈活地使用JOIN,不少分析師或數(shù)據(jù)庫(kù)管理員(DBA)都會(huì)選用Arctype for MySQL之類的工具,去生成復(fù)雜、完整的JOIN子句,以避免去記憶那些數(shù)百條條列名或別名。此外,此類自動(dòng)化工具還能夠通過(guò)豐富的功能,協(xié)助用戶創(chuàng)建復(fù)雜的查詢,并能夠輕松地管理JOIN的各項(xiàng)條件。
原文標(biāo)題:A Guide to MySQL JOINs,作者:Blessing Krofegha
【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請(qǐng)注明原文譯者和出處為51CTO.com】