MySQL JOIN 語法概述
SQL(MySQL)JOIN用於根據兩個或多個表中的字段之間的關係,從這些表中得到數據。
JOIN通常與ON關鍵字搭配使用,基本語法如下:
... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON conditiona
table1通常稱爲左表,table2稱爲右表。ON關鍵字用於設定匹配條件,用於限定在結果集合中想要哪些行。如果需要指定其他條件,後面可以加上 WHERE條件 或者 LIMIT 以限制記錄返回數目等。
下面以最常見的兩表連接來說明MySQLJOIN 的用法,關於多表JOIN請參見《MySQLJOIN 多表》。
MySQLJOIN 分類
JOIN按照功能大致分爲如下三類:
-
INNERJOIN(內連接):取得兩個表中存在連接匹配關係的記錄。
-
LEFTJOIN(左連接):取得左表(table1)完全記錄,即是右表(table2)並無對應匹配記錄。
-
RIGHTJOIN(右連接):與LEFTJOIN 相反,取得右表(table2)完全記錄,即是左表(table1)並無匹配對應記錄。
關於MySQLFULL JOIN 全連接
MySQL沒有提供SQL標準中的FULLJOIN(全連接):兩個表記錄都取出,而不管彼此是否有對應記錄。要解決此問題,可以使用UNION關鍵字來合併LEFTJOIN 與RIGHTJOIN,達到模擬FULLJOIN 的目的。
MySQLINNER JOIN
INNERJOIN 用於取得兩個表中存在連接匹配關係的記錄。下面是兩個原始數據表:
article文章表:
aid |
title |
content |
uid |
---|---|---|---|
1 |
文章1 |
文章1正文內容... |
1 |
2 |
文章2 |
文章2正文內容... |
1 |
3 |
文章3 |
文章3正文內容... |
2 |
4 |
文章4 |
文章4正文內容... |
4 |
user用戶表:
uid |
username |
|
---|---|---|
1 |
admin |
|
2 |
小明 |
|
3 |
Jack |
article表中文章的所屬用戶是通過uid這個字段與user表關聯起來的。通過觀察數據不難發現,對於uid=3的用戶,並沒有發表任何文章;而文章中aid=4卻無法在uid表中找到對應記錄(可能是該用戶被刪除而其所屬的文章卻被保留了下來)。
我們列出所用文章與用戶一一對應的數據。
SELECT... INNER JOIN ... ON 語句如下:
SELECT article.aid,article.title,user.username FROM article INNER JOIN user ON article.uid = user.uid
返回查詢結果如下:
aid |
title |
username |
---|---|---|
1 |
文章1 |
admin |
2 |
文章2 |
admin |
3 |
文章3 |
小明 |
對於INNERJOIN,等同與下面的SQL語句:
SELECT article.aid,article.title,user.username FROM article,user WHERE article.uid = user.uid
CROSSJOIN
CROSSJOIN 即交叉連接,在不指定ON條件下:
SELECT article.aid,article.title,user.username FROM article CROSS JOIN user
得到的結果是被連接的兩個數據表的乘積,即笛卡爾積。
實際上,在MySQL中(僅限於MySQL)CROSSJOIN 與INNERJOIN 的表現是一樣的,在不指定ON條件得到的結果都是笛卡爾積,反之取得兩個表完全匹配的結果。
INNERJOIN 與CROSSJOIN 可以省略INNER或CROSS關鍵字,因此下面的SQL效果是一樣的:
... FROM table1 INNER JOIN table2 ... FROM table1 CROSS JOIN table2 ... FROM table1 JOIN table2
MySQLLEFT JOIN 語法
SQL(MySQL)LEFTJOIN 會取得左表(table1)全部記錄,即使右表(table2)並無對應匹配記錄。LEFTJOIN 基本語法如下:
... FROM table1 LEFT JOIN table2 ON condition ...
MySQLLEFT JOIN 用法實例
下面是兩個原始數據表:
article文章表:
aid |
title |
content |
uid |
---|---|---|---|
1 |
文章1 |
文章1正文內容... |
1 |
2 |
文章2 |
文章2正文內容... |
1 |
3 |
文章3 |
文章3正文內容... |
2 |
4 |
文章4 |
文章4正文內容... |
4 |
user用戶表:
uid |
username |
|
---|---|---|
1 |
admin |
|
2 |
小明 |
|
3 |
Jack |
我們列出所有的文章及對應的所屬用戶,即使沒有用戶的文章也列出。
SELECT... LEFT JOIN ... ON 語句如下:
SELECT article.aid,article.title,user.username FROM article LEFT JOIN user ON article.uid = user.uid
返回查詢結果如下:
aid |
title |
username |
---|---|---|
1 |
文章1 |
admin |
2 |
文章2 |
admin |
3 |
文章3 |
小明 |
4 |
文章4 |
NULL |
可以看出來,與 INNERJOIN 明顯的區別是,左表記錄被全部取出,即使右表無對應匹配記錄。
提示
這裏所謂記錄被“全部”取出,是相對於INNERJOIN 的限制來說的。其實可以在上面的SQL語句後面加個WHERE條件或者LIMIT等關鍵字以同一般SQL語句一樣對結果集做一個範圍限制。
ISNULL
在上面的例子中,對於右表中沒有對應匹配的數據記錄,其所有的列都被置爲NULL,因此要查詢這部分記錄(如在上面例子中體現爲查找aid=4這類無對應用戶的文章記錄),可以附加ISNULL 條件:
SELECT article.aid,article.title,user.username FROM article LEFT JOIN user ON article.uid = user.uid WHERE user.uid IS NULL
MySQLRIGHT JOIN 語法
SQL(MySQL)RIGHTJOIN 會取得右表(table2)全部記錄,即使左表(table2)並無對應匹配記錄。RIGHTJOIN 基本語法如下:
... FROM table1 RIGHT JOIN table2 ON condition ...
MySQLRIGHT JOIN 用法實例
下面是兩個原始數據表:
article文章表:
aid |
title |
content |
uid |
---|---|---|---|
1 |
文章1 |
文章1正文內容... |
1 |
2 |
文章2 |
文章2正文內容... |
1 |
3 |
文章3 |
文章3正文內容... |
2 |
4 |
文章4 |
文章4正文內容... |
4 |
user用戶表:
uid |
username |
|
---|---|---|
1 |
admin |
|
2 |
小明 |
|
3 |
Jack |
我們列出所有的用戶,以及他們可能擁有的文章。
SELECT... RIGHT JOIN ... ON 語句如下:
SELECT article.aid,article.title,user.username FROM article RIGHT JOIN user ON article.uid = user.uid
返回查詢結果如下:
aid |
title |
username |
---|---|---|
1 |
文章1 |
admin |
2 |
文章2 |
admin |
3 |
文章3 |
小明 |
NULL |
NULL |
Jack |
對比 LEFTJOIN 返回的查詢結果,RIGHTJOIN 返回的結果與其剛好“相反”。
ISNULL
在上面的例子中,對於左表中沒有對應匹配的數據記錄,其所有的列都被置爲NULL,因此要查詢這部分記錄(如在上面例子中體現爲查找username=Jack這類無對應文章的所有用戶),可以附加ISNULL 條件:
SELECT article.aid,article.title,user.username FROM article LEFT JOIN user ON article.uid = user.uid WHERE article.aid IS NULL
MySQLJOIN 多表連接
除了常用的兩個表連接之外,SQL(MySQL)JOIN語法還支持多表連接。多表連接基本語法如下:
... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON condition INNER|LEFT|RIGHT JOIN table3 ON condition ...
JOIN多表連接實現了從多個表中獲取相關數據,下面是三個原始數據表:
article文章表:
aid |
title |
content |
uid |
tid |
---|---|---|---|---|
1 |
文章1 |
文章1正文內容... |
1 |
1 |
2 |
文章2 |
文章2正文內容... |
1 |
2 |
3 |
文章3 |
文章3正文內容... |
2 |
1 |
5 |
文章5 |
文章5正文內容... |
4 |
1 |
user用戶表:
uid |
username |
|
---|---|---|
1 |
admin |
|
2 |
小明 |
|
3 |
Jack |
type文章類型表:
tid |
typename |
---|---|
1 |
普通文章 |
2 |
精華文章 |
3 |
草稿 |
MySQLINNER JOIN 多表
我們使用 INNERJOIN 列出三個表中都具有關聯關係的數據:
SELECT article.aid,article.title,user.username,type.typename FROM article INNER JOIN user ON article.uid=user.uid INNER JOIN type ON article.tid=type.tid
返回查詢結果如下:
aid |
title |
username |
typename |
---|---|---|---|
1 |
文章1 |
admin |
普通文章 |
2 |
文章2 |
admin |
精華文章 |
3 |
文章3 |
小明 |
普通文章 |
MySQLLEFT JOIN 多表
使用 LEFTJOIN 三個表查詢:
SELECT article.aid,article.title,user.username,type.typename FROM article LEFT JOIN user ON article.uid=user.uid LEFT JOIN type ON article.tid=type.tid
返回查詢結果如下:
aid |
title |
username |
typename |
---|---|---|---|
1 |
文章1 |
admin |
普通文章 |
2 |
文章2 |
admin |
精華文章 |
3 |
文章3 |
小明 |
普通文章 |
4 |
文章4 |
NULL |
普通文章 |
MySQLRIGHT JOIN 多表
使用 RIGHTJOIN 三個表查詢:
SELECT article.aid,article.title,user.username,type.typename FROM article RIGHT JOIN user ON article.uid=user.uid RIGHT JOIN type ON article.tid=type.tid
返回查詢結果如下:
aid |
title |
username |
typename |
---|---|---|---|
1 |
文章1 |
admin |
普通文章 |
2 |
文章2 |
admin |
精華文章 |
3 |
文章3 |
小明 |
普通文章 |
NULL |
NULL |
NULL |
草稿 |
可見,在RIGHTJOIN 右連接中,只是列出最後一個右連接表的所有數據。
說明
對於MySQL多表JOIN,還可以INNER、LEFT和RIGHT混用,其返回結果與各關鍵字順序有關,感興趣可自行測試。
MySQLSTRAIGHT_JOIN
STRAIGHT_JOIN是MySQL對標準SQL的擴展,用於在多表查詢時指定表載入的順序。在JOIN表連接中,同樣可以指定表載入的順序,本文只講述STRAIGHT_JOIN在表連接JOIN中的應用。
MySQLSTRAIGHT_JOIN 語法如下:
... FROM table1 STRAIGHT_JOIN table2 ON condition ...
STRAIGHT_JOIN實際上與內連接INNERJOIN 表現完全一致,不同的是使用了STRAIGHT_JOIN後,table1會先於table2載入。
提示
MySQL在執行INNERJOIN 的時候,會根據自己內部的優化規則來決定先載入table1還是table2,如果您確認MySQL載入表的順序並不是最優化的時候,就可以使用STRAIGHT_JOIN以替代INNERJOIN。
MySQLSTRAIGHT_JOIN 例子
SELECT article.aid,article.title,user.username FROM article STRAIGHT_JOIN user ON article.uid=user.uid
注意:該SQL僅僅是STRAIGHT_JOIN使用示例,並不表示其合理性。
如果有更多表進行連接,那麼使用STRAIGHT_JOIN後,其載入順序就遵循從左往右的規則。最後,STRAIGHT_JOIN無法應用於LEFTJOIN 或RIGHTJOIN。
MySQLNATURAL JOIN
NATURALJOIN 也叫自然連接,實際是屬於JOIN的一種。
MySQLNATURAL JOIN 語法如下:
... FROM table1 NATURAL JOIN table2 ...
使用NATURALJOIN 時,MySQL將表中具有相同名稱的字段自動進行記錄匹配,而這些同名字段類型可以不同。因此,NATURALJOIN 不用指定匹配條件。
NATURALJOIN 默認是同名字段完全匹配的INNERJOIN,也可以使用 LEFTJOIN 或 RIGHTJOIN。一些例子如下:
SELECT article.aid,article.title,user.username FROM article NATURAL JOIN user // LEFT SELECT article.aid,article.title,user.username FROM article NATURAL LEFT JOIN user // RIGHT SELECT article.aid,article.title,user.username FROM article NATURAL RIGHT JOIN user