關系數據庫由多個相關表組成,這些表使用已知為外鍵列的常用列鏈接在一起。 因此,從業務角度來看,每個表中的數據是不完整的。
例如,在示例數據庫(yiibaidb)中,使用orderNumber
列鏈接的orders
和orderdetails
表。
orders
和orderdetails
表的 ER 圖如下所示 -
要獲取完整的訂單數據,需要從訂單(orders
)和訂單詳細(orderdetails
)表中查詢數據。
這就是為什么要使用連接表了。
MySQL連接是一種基於表之間的公共列的值來鏈接來自一個(自連接)或更多表的數據的方法。
MySQL支持以下類型的連接:
要連接表,可以對相應類型的連接使用CROSS JOIN
,INNER JOIN
,LEFT JOIN
或RIGHT JOIN
子句。 在SELECT語句中的FROM
子句之后使用了連接子句。
請注意,MySQL不支持完全外部連接。
為了方便您了解每種類型的連接,我們將使用具有以下結構的兩個表:t1
和t2
表:
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 );
t1
和t2
表中都有pattern
列,此列也是這兩個表之間的公共列。執行以下查詢語句將數據插入到t1
和t2
表中:
INSERT INTO t1(id, pattern) VALUES(1,'Divot'), (2,'Brick'), (3,'Grid'); INSERT INTO t2(id, pattern) VALUES('A','Brick'), ('B','Grid'), ('C','Diamond');
現在兩個表中的數據如下所示 -
2. MySQL交叉連接(CROSS JOIN)
CROSS JOIN
生成來自多個表的行的笛卡爾乘積。假設您使用CROSS JOIN
來連接t1
和t2
表,結果集將包括t1
表中的行與t2
表中的行的組合。
要執行交叉連接(最后得到迪卡爾乘積),請使用CROSS JOIN
子句,如以下語句所示:
SELECT t1.id, t2.id FROM t1 CROSS JOIN t2;
執行上面語句,得到以下結果 -
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
如您所見,t1
表中的每一行與t2
表中的行結合形成笛卡爾乘積。
下圖顯示了t1
和t2
表之間的CROSS JOIN
連接 -
3. MySQL內連接(INNER JOIN)
要形成一個INNER JOIN
連接子句,需要一個稱為連接謂詞的條件。 INNER JOIN
需要兩個連接的表中的行具有匹配的列值。 INNER JOIN
通過組合基於連接謂詞的兩個連接表的列值來創建結果集。
要連接兩個表,INNER JOIN
將第一個表中的每一行與第二個表中的每一行進行比較,以找到滿足連接謂詞的行對。每當通過匹配非NULL
值來滿足連接謂詞時,兩個表中每個匹配的行對的列值將包含在結果集中(可以簡單地理解為兩個表的交集)。
以下語句使用INNER JOIN
子句來連接t1
和t2
表:
SELECT t1.id, t2.id FROM t1 INNER JOIN t2 ON t1.pattern = t2.pattern;
在上面語句中,以下表達式是連接謂詞:
t1.pattern = t2.pattern
這意味着t1
和t2
表中的行必須在pattern
列中具有相同的值才能包含在結果中。
以下查詢的結果可以說明:
+----+----+ | id | id | +----+----+ | 2 | A | | 3 | B | +----+----+
下圖顯示了t1
和t2
表之間的INNER JOIN
:
在此圖中,兩個表中的行必須具有相同pattern
列值,才能包含在結果集中。
4. MySQL左連接(LEFT JOIN)
類似於INNER JOIN
,LEFT JOIN
也需要連接謂詞。當使用LEFT JOIN
連接兩個表時,介紹了左表和右表的概念。
與INNER JOIN
不同,LEFT JOIN
返回左表中的所有行,包括滿足連接謂詞的行。 對於不匹配連接謂詞的行,右表中的列將使用NULL
值顯示在結果集中。
以下語句使用LEFT JOIN
子句來連接t1
和t2
表:
SELECT t1.id, t2.id FROM t1 LEFT JOIN t2 ON t1.pattern = t2.pattern ORDER BY t1.id;
執行上面查詢,得到以下結果 -
+----+------+ | id | id | +----+------+ | 1 | NULL | | 2 | A | | 3 | B | +----+------+ 3 rows in set
如上所見,t1
表中的所有行都包含在結果集中。 對於t2
表(右表)中沒有任何匹配t1
表(左表)中的行,在t2
表中的列使用NULL
顯示。
下圖顯示了在t1
和t2
表上使用LEFT JOIN
子句:
在此圖中,以下行具有相同的pattern
:(2
和A
),(3
和B
)。 t1
表中ID
為1
的行在t2
表中沒有匹配的行,因此,在結果集中的t2
表的列使用NULL
代替顯示。
5. MySQL右連接(RIGHT JOIN)
右連接(RIGHT JOIN
)類似於右連接(LEFT JOIN
),除了表的處理是相反的。使用RIGHT JOIN
,右表格(t2
)中的每一行將顯示在結果集中。 對於右表中沒有左表(t1
)中的匹配行的行,左表(t1
)中的列會顯示NULL
。
以下語句使用RIGHT JOIN
連接t1
和t2
表:
SELECT t1.id, t2.id FROM t1 RIGHT JOIN t2 on t1.pattern = t2.pattern ORDER BY t2.id;
執行上面是查詢語句,得到下面結果 -
+------+----+
| id | id |
+------+----+
| 2 | A |
| 3 | B |
| NULL | C |
+------+----+
3 rows in set
在此結果中,來自右表(t2
)的所有行都顯示在結果集中。對於左表(t1
)中沒有匹配右表(t2
)中的行,則左表(t1
)的列將使用NULL
代替顯示。
下圖顯示了t1
和t2
表之間的右連接(RIGHT JOIN
):
在本教程中,您已經學習了各種MySQL連接語句,包括交叉連接,內部連接,左連接和右連接,以從兩個或多個表查詢數據。