1. 程式人生 > >MySQL連線查詢(inner join,left join和right join的區別)

MySQL連線查詢(inner join,left join和right join的區別)

關係資料庫由多個相關表組成,這些表使用已知為外來鍵列的常用列連結在一起。 因此,從業務角度來看,每個表中的資料是不完整的。

例如,在示例資料庫(yiibaidb)中,使用orderNumber列連結的ordersorderdetails表。

ordersorderdetails表的 ER 圖如下所示 - 

要獲取完整的訂單資料,需要從訂單(orders)和訂單詳細(orderdetails)表中查詢資料。

這就是為什麼要使用連線表了。

MySQL連線是一種基於表之間的公共列的值來連結來自一個(自連線)或更多表的資料的方法。

MySQL支援以下型別的連線:

要連線表,可以對相應型別的連線使用CROSS JOININNER JOINLEFT JOINRIGHT JOIN子句。 在SELECT語句中的FROM子句之後使用了連線子句。

請注意,MySQL不支援完全外部連線。

為了方便您瞭解每種型別的連線,我們將使用具有以下結構的兩個表:t1t2表:

USE testdb;

CREATE TABLE t1 ( id INT PRIMARY KEY, pattern VARCHAR(50) NOT NULL ); CREATE TABLE t2 ( id VARCHAR(50) PRIMARY KEY, pattern VARCHAR(50) NOT NULL ); 
SQL

t1t2表中都有pattern列,此列也是這兩個表之間的公共列。執行以下查詢語句將資料插入到t1t2表中:

INSERT INTO t1(id, pattern) VALUES(1,'Divot'), (2,'Brick'), (3,'Grid'); INSERT INTO t2(id, pattern) VALUES('A','Brick'), ('B','Grid'), ('C','Diamond'); 
SQL

現在兩個表中的資料如下所示 - 

2. MySQL交叉連線(CROSS JOIN)

CROSS JOIN

生成來自多個表的行的笛卡爾乘積。假設您使用CROSS JOIN來連線t1t2表,結果集將包括t1表中的行與t2表中的行的組合。

要執行交叉連線(最後得到迪卡爾乘積),請使用CROSS JOIN子句,如以下語句所示:

SELECT 
    t1.id, t2.id
FROM t1 CROSS JOIN t2; 
SQL

執行上面語句,得到以下結果 - 

mysql> SELECT 
    t1.id, t2.id FROM t1 CROSS JOIN t2; +----+----+ | id | id | +----+----+ | 1 | A | | 2 | A | | 3 | A | | 1 | B | | 2 | B | | 3 | B | | 1 | C | | 2 | C | | 3 | C | +----+----+ 9 rows in set 
SQL

如您所見,t1表中的每一行與t2表中的行結合形成笛卡爾乘積。

下圖顯示了t1t2表之間的CROSS JOIN連線 - 

3. MySQL內連線(INNER JOIN)

要形成一個INNER JOIN連線子句,需要一個稱為連線謂詞的條件。 INNER JOIN需要兩個連線的表中的行具有匹配的列值。 INNER JOIN通過組合基於連線謂詞的兩個連線表的列值來建立結果集。

要連線兩個表,INNER JOIN將第一個表中的每一行與第二個表中的每一行進行比較,以找到滿足連線謂詞的行對。每當通過匹配非NULL值來滿足連線謂詞時,兩個表中每個匹配的行對的列值將包含在結果集中(可以簡單地理解為兩個表的交集)。

以下語句使用INNER JOIN子句來連線t1t2表:

SELECT 
    t1.id, t2.id
FROM t1 INNER JOIN t2 ON t1.pattern = t2.pattern; 
SQL

在上面語句中,以下表達式是連線謂詞:

t1.pattern = t2.pattern
SQL

這意味著t1t2表中的行必須在pattern列中具有相同的值才能包含在結果中。

以下查詢的結果可以說明:

+----+----+
| id | id | +----+----+ | 2 | A | | 3 | B | +----+----+ 
SQL

下圖顯示了t1t2表之間的INNER JOIN

在此圖中,兩個表中的行必須具有相同pattern列值,才能包含在結果集中。

4. MySQL左連線(LEFT JOIN)

類似於INNER JOINLEFT JOIN也需要連線謂詞。當使用LEFT JOIN連線兩個表時,介紹了左表和右表的概念。

INNER JOIN不同,LEFT JOIN返回左表中的所有行,包括滿足連線謂詞的行。 對於不匹配連線謂詞的行,右表中的列將使用NULL值顯示在結果集中。

以下語句使用LEFT JOIN子句來連線t1t2表:

SELECT 
    t1.id, t2.id
FROM t1 LEFT JOIN t2 ON t1.pattern = t2.pattern ORDER BY t1.id; 
SQL

執行上面查詢,得到以下結果 - 

+----+------+
| id | id   | +----+------+ | 1 | NULL | | 2 | A | | 3 | B | +----+------+ 3 rows in set 
SQL

如上所見,t1表中的所有行都包含在結果集中。 對於t2表(右表)中沒有任何匹配t1表(左表)中的行,在t2表中的列使用NULL顯示。

下圖顯示了在t1t2表上使用LEFT JOIN子句:

在此圖中,以下行具有相同的pattern:(2A),(3B)。 t1表中ID1的行在t2表中沒有匹配的行,因此,在結果集中的t2表的列使用NULL代替顯示。

5. MySQL右連線(RIGHT JOIN)

右連線(RIGHT JOIN)類似於右連線(LEFT JOIN),除了表的處理是相反的。使用RIGHT JOIN,右表格(t2)中的每一行將顯示在結果集中。 對於右表中沒有左表(t1)中的匹配行的行,左表(t1)中的列會顯示NULL

以下語句使用RIGHT JOIN連線t1t2表:

SELECT 
    t1.id, t2.id
FROM t1 RIGHT JOIN t2 on t1.pattern = t2.pattern ORDER BY t2.id; 
SQL

執行上面是查詢語句,得到下面結果 - 

+------+----+
| id   | id |
+------+----+
|    2 | A  |
|    3 | B  |
| NULL | C  |
+------+----+
3 rows in set
Shell

在此結果中,來自右表(t2)的所有行都顯示在結果集中。對於左表(t1)中沒有匹配右表(t2)中的行,則左表(t1)的列將使用NULL代替顯示。

下圖顯示了t1t2表之間的右連線(RIGHT JOIN):

在本教程中,您已經學習了各種MySQL連線語句,包括交叉連線,內部連線,左連線和右連線,以從兩個或多個表查詢資料。