在資料庫中管理資料時,將資訊組織到單獨的表中可以提高效能並保持一致性。但是,為了完成某些查詢,往往需要將多個表中的資料合併起來。連線表可以根據共享欄位值匹配記錄,從而實現這一目的。
例如,將“customers”表與“orders”表連線起來,就可以在一次查詢中檢索訂單和相應的客戶資訊。
不同型別的連線提供了各種組合表資料的方法。在本教學指南中,我們將學習如何在 MySQL 中連線兩個或多個表、為什麼這樣做以及如何使實現。
什麼是MySQL中的Joins?
簡而言之,MySQL 連線可讓您訪問多個表中的資料。只要在 SQL 語句中連線兩個或多個表,就會執行 MySQL 連線。
SQL 連線語句的基本格式如下:
SELECT * FROM <first_table> <join_type> <second_table> <join_condition>;
資料庫連線(Database Joins)會根據不同資料來源中特定列的匹配值,將記錄合併在一起。每個結果行都包含來自第一張表和第二張表的資料,並根據共享的列值進行對齊。
在連線操作中,每一行都包含第一張表的所有列,接著是第二張表的所有列。你可以在查詢的 SELECT 部分指定要顯示哪些列。
MySQL的連線型別包括:
- MySQL內連線(Inner Join,亦稱簡單連線)
- MySQL左外連線(Left Outer Join,亦稱左連線,它返回左表中的匹配記錄)
- 右連線(Right Join,此連線返回右表中的匹配記錄)
- 全連線(Full Join,此連線返回所有表中的匹配記錄)
連線的型別以及指定的條件決定了每一行結果的構建方式,以及如何處理不滿足連線條件的表中的行。
例如,內連線可以用於將“customers”表與“orders”表結合起來,從而檢索訂單及其對應的客戶資訊。
如何在MySQL中連線多個表?
如果您正在開發一個大型應用程式(如電子商務商店),並在其中建立了多個表(如客戶、訂單和產品),您可能需要連線表。
讓我們來看一個例子,在這個例子中,我們要獲取特定客戶訂購的所有產品。
讓我們建立查詢:
SELECT * FROM table1 LEFT JOIN table2 ON table2.id = table1.id LEFT JOIN table3 ON table3.id = table1.id
如果檢視上面的查詢,我們首先連線表 1 和表 2,得到一個包含表 1 和表 2 合併資料的臨時表,然後將其連線到表 3。這個等式可以擴充套件到多於 3 個表的 N 個表。您需要確保 SQL 查詢有 N-1 個連線語句,以便連線 N 個表。
透過上述查詢,可以將表 1(在任何情況下)的記錄與其他兩個表的記錄進行匹配。使用 LEFT JOIN 可以將表 2 和表 3 與表 1連線起來(而不只是將表 2 與表 1 連線起來,將表 3 與表 2 連線起來)。
還可以新增WHERE、AND 和 ORDER BY 等條件:
SELECT * FROM table1 LEFT JOIN table2 ON table2.id = table1.id LEFT JOIN table3 ON table3.id = table1.id WHERE month = 'numberHere' AND (table2.email IS NOT NULL OR table3.email IS NOT NULL) ORDER BY submitdate DESC
在MySQL中可以連線多少個表?
根據 MySQL 8.0 的官方文件,JOIN 語句中表的最大數量是 61。不過,請注意,隨著表數量的增加,JOIN 語句可能會佔用大量伺服器資源。如果您的查詢屬於這種情況,我強烈建議您將其分解為多個查詢,以減少伺服器負載。
MySQL中的連線型別
連線有不同的型別,每種型別都能產生不同的資料集。瞭解它們的工作原理可以幫助您選擇最合適的連線,以實現查詢所需的資料結果。
- 內連線(Inner Join)
- 右連線(Right Join)
- 左連線(Left Join)
- 並集(Union)
- 交叉連線或笛卡爾積(Cross Join)
- 自連線(Self Join)
- 全外連線(Full Outer Join)
- 自然連線(Natural Join)
為了演示每種連線型別的行為,讓我們考慮有兩個表的情況:myguests 表和 messages 表。
messages 表的模式
我們將建立一個名為“messages”的表來儲存訊息和傳送者的使用者 ID。下面是我們的表的模式:
CREATE TABLE `messages` ( `id` int(11) NOT NULL, `message` varchar(255) NOT NULL );
該表將作為我們測試每種連線型別的參考。
內連線
在 MySQL 中,預設的連線型別是內部連線。可以使用 INNER JOIN 或 JOIN 來指定。此外,MySQL 還支援 CROSS JOIN。在某些資料庫系統中,INNER JOIN 和 CROSS JOIN 是兩個獨立的概念,而 MySQL 則不同,它將這兩個概念合併為一個結構。
Inner Join 查詢的結構如下:
SELECT column_name(s) FROM table1 INNER JOIN table2 ON table1.column_name=table2.column_name;
Inner Join 和 simple Join 是一樣的。您也可以這樣編寫查詢:
SELECT column_name(s) FROM table1 JOIN table2 ON table1.column_name=table2.column_name;
現在,讓我們使用內部連線從資料庫中獲取姓名和資訊。查詢結果如下:
$sql = "SELECT CONCAT(myguests.firstname,' ',myguests.lastname) AS name, myguests.email, messages.message From myguests INNER JOIN messages ON myguests.id = messages.id";
在 MySQL 中,CONCAT 函式用於連線兩個字串列。現在開啟我們之前建立的 index.php,複製以下程式碼。
<table> <tr> <td> Name</td> <td> Email</td> <td> Message</td> <!-- <td> Message</td> <td> Date</td>!--> </tr> <?php include 'crud.php'; $sql = "SELECT CONCAT(myguests.firstname,' ',myguests.lastname) AS name, myguests.email, messages.message From myguests INNER JOIN messages ON myguests.id = messages.id"; $result = selectdata($sql); if($result != "zero") { while($row = $result->fetch_assoc()) { echo "<tr>"; echo "<td>" . $row['name'] . "</td>"; echo "<td>" . $row['email'] . "</td>"; if($row['message'] === null){echo "<td>" . 'null'. "</td>";} else { echo "<td>" . $row['message']. "</td>"; } ; echo "</tr>"; } } else { echo $result; } ?> </table> ?>
在 PHP 主機伺服器上執行該頁面時,結果將如下所示:
可以清楚地看到,它只返回了符合user_id且訊息不為空的結果。
右連線
RIGHT JOIN 將表結合起來,返回右表的所有值和左表的匹配值。當沒有找到匹配值時,它還包括左表中的 NULL 值。
RIGHT JOIN 的結構是:
SELECT column_name(s) FROM table1 RIGHT JOIN table2 ON table1.column_name=table2.column_name;
假設我們要從資料庫中獲取姓名和訊息,右表為訊息,左表為 myguests。查詢將是:
$sql = "SELECT CONCAT(myguests.firstname,' ',myguests.lastname) AS name, myguests.email, messages.message From myguests RIGHT JOIN messages ON messages.id = myguests.id";
該查詢會返回 messages
表中的所有訊息。對於每條訊息,它還會從myguests
表中獲取相應的姓名和電子郵件(如果有的話)。如果myguests
表中沒有匹配的 ID,則姓名和電子郵件將返回 NULL 值。
現在開啟 index.php,將 $sql 查詢替換為上述內容。執行後,結果將如下:
如果檢視上面截圖中的訊息表,你會發現一些 ID 與任何使用者 ID 都不匹配。這就是為什麼該查詢在姓名和電子郵件列中返回空值,因為它在左列中沒有找到任何匹配項。
左連線
LEFT JOIN 連線兩個表時,會返回左表中的所有值和右表中的匹配值,如果沒有找到匹配值,還會在右表中返回 NULL。LEFT JOIN 的結構如下:
SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.column_name=table2.column_name;
現在,讓我們以“messages”表為右表,以“myguests”表為左表,從資料庫中獲取“Name”和“message”。
$sql = "SELECT CONCAT(myguests.firstname,' ',myguests.lastname) AS name, myguests.email, messages.message From myguests LEFT JOIN messages ON messages.id = myguests.id";
現在開啟 index.php,將 $sql 查詢替換為上述內容。執行後,結果如下:
如果檢視訊息表,你會發現一些 ID 與任何使用者 ID 都不匹配。這就是為什麼此查詢在 Message 列中返回 NULL,而在右列中找不到任何匹配的原因。
並集
MySQL 中的 UNION 將來自不同表的多個列合併為一個結果集。用於選擇唯一值的 UNION 查詢的結構是
SELECT column_name(s) FROM table1 UNION SELECT column_name(s) FROM table2;
以及從列中選擇重複值:
SELECT column_name(s) FROM table1 UNION ALL SELECT column_name(s) FROM table2;
現在,讓我們從表中獲取 ID。
$sql = "SELECT id FROM myguests UNION SELECT id FROM messages";
現在開啟 index.php,將 $sql 查詢替換為上面的查詢。執行後,結果將是:
查詢獲取了兩個表中的所有唯一 ID。
交叉連線或笛卡爾積
這種型別的聯接會返回聯接表中記錄的笛卡爾積。它將返回一個由第一張表的每條記錄和第二張表的每條記錄組成的表。
交叉連線的語法是:
SELECT column-name-list from table-name1 CROSS JOIN table-name2;
現在,讓我們用“myguests”表和“messages”表來展示 Cross JOIN:
假設我們想列出“myguests”表中姓名與“messages”表中資訊的所有可能組合。我們可以使用交叉連線來實現這一目的:
SELECT myguests.firstname, myguests.lastname, messages.message FROM myguests CROSS JOIN messages;
該查詢將給出一個列表,其中包含“myguests”表中的姓名和“messages”表中的訊息的所有組合。
自連線
自連線是一種將表中的行與表本身結合起來的連線型別。雖然我們可能無法立即看出它的用處,但它實際上有許多常見的應用。
自連線語法:
SELECT column_name(s) FROM table1 T1, table1 T2 WHERE condition;
現在,讓我們用“messages”表演示一下自連線:
假設我們要查詢發件人相同的郵件對。我們可以使用自連線來實現這一目的:
SELECT m1.id, m1.sender, m2.id, m2.sender FROM messages m1, messages m2 WHERE m1.sender = m2.sender AND m1.id <> m2.id;
此查詢將返回具有相同發件人的成對郵件,但不包括將郵件與自身進行比較的情況。
自連線在需要比較同一表中的行時特別有用,例如在分層結構或處理遞迴關係時。
全外連線
當左表(表 1)或右表(表 2)中的記錄出現匹配時,全外連線會返回所有記錄。它基本上結合了左連線和右連線的結果。
注意:全外連線可能會返回非常大的結果集!
全外連線語法:
SELECT column_name(s) FROM table1 FULL OUTER JOIN table2 ON table1.column_name = table2.column_name;
下面有一個簡單的例子來說明全外連線:
假設我們有兩個表,“employees”和“departments”,我們要檢索兩個表中的所有記錄,包括匹配記錄和未匹配記錄:
SELECT e.employee_id, e.employee_name, d.department_name FROM employees e FULL OUTER JOIN departments d ON e.department_id = d.department_id;
此查詢將返回所有團隊成員記錄(包括沒有相應部門的記錄)和所有部門記錄(包括沒有任何相關僱員的記錄)。
自然連線
自然連線是 SQL 中的一種連線型別,它根據具有相同名稱和資料型別的列來合併表中的記錄。這種連線只在結果集中包含一次常見列。
要使用自然連線,可以使用以下語法將兩個或多個表結合起來:
SELECT column_1, column_2, ..., column_n FROM table_1 NATURAL JOIN table_2;
讓我們用“messages”表來說明自然連線:
假設我們有兩個表,“messages”表和“users”表,這兩個表都包含一個名為“user_id”的列。我們的目標是從兩個表中獲取“user_id”列值匹配的所有記錄:
SELECT * FROM messages NATURAL JOIN users;
該查詢將對“user_id”列執行自然連線,合併兩個表中“user_id”值匹配的記錄。生成的資料集將只顯示一次“user_id”列。
總結
現實世界中幾乎所有的資料查詢都要使用 SQL 中的某種連線。連線就像拼圖一樣,可以幫助我們從不同來源收集資訊。
在本文中,我們討論了 SQL 連線以及 MySQL 如何使用它們來組合來自不同表的資料。
透過了解連線,你就能在 PHP 應用程式中順利處理資料,無論其結構如何。
常見問題
Q1. 使用什麼 SQL 命令可以連線兩個表?
答:可以使用 SQL 中的 INNER JOIN 命令,根據共同的列合併兩個表。它只檢索兩個表中匹配的記錄,確保以結構化和高效的方式合併相關資料。
例如:
SELECT orders.order_id, customers.customer_name FROM orders INNER JOIN customers ON orders.customer_id = customers.customer_id;
Q2. 如何在 MySQL 中連線兩個資料庫?
答:在 MySQL 中,可以使用 JOIN 語句連線兩個不同資料庫的表。語法格式如下:
SELECT tb_1.*, tb_2.* FROM database_1.table_name_1 tb_1 JOIN database_2.table_name_2 tb_2 ON tb_1.id = tb_2.id;
該查詢透過使用 database_name.table_name 引用不同資料庫中的表來檢索匹配記錄。
Q3. 如何用 SQL 連線多對多關係的兩個表?
答:要連線具有多對多關係的兩個表,請使用包含兩個表外部索引鍵的連線表。
例如,如果有事件和參與者,可以使用 event_participants 這樣的連線表將它們連線起來。然後,使用內聯連線檢索相關記錄:
SELECT e.event_name, p.participant_name FROM events e JOIN event_participants ep ON e.id = ep.event_id JOIN participants p ON ep.participant_id = p.id;
Q4. 可以連線沒有任何關係的兩個表嗎?
答:可以。要連線兩個沒有任何關係的表,可以使用 CROSS JOIN 或 UNION。
- CROSS JOIN 將一個表中的每一條記錄與另一個表中的每一條記錄配對。
- UNION 將兩個 SELECT 查詢的結果合併為一個結果,只要這兩個表具有相同的結構。
這兩種方法都允許合併表,即使沒有共享鍵或關係。
Q5. 我們可以連線兩個列名相同的 MySQL 表嗎?
答:可以,你可以連線列名相同的兩個 MySQL 表。為避免混淆,請使用別名來區分列。這可確保正確連線表而不會出現任何問題。
例如:
SELECT t1.column_name AS t1_column, t2.column_name AS t2_column FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id;
Q6. 如何在 SQL 和 MySQL 中連線三個表?
答:要在 SQL 或 MySQL 中連線三個表,可以使用多重連線。只需連線前兩個表,然後將第三個表連線到第一個連線的結果。這樣做不一定需要子查詢,因為可以在單個查詢中直接連線所有表。
例如
SELECT t1.column1, t2.column2, t3.column3 FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id JOIN table3 t3 ON t2.id = t3.id;
Q7. 如何在不使用連線的情況下用 SQL 連線兩個表?
答:在 SQL 中可以不使用 JOIN 關鍵字連線兩個表,方法是在 FROM 子句中列出兩個表,中間用逗號隔開。這被稱為隱式連線。
例如
SELECT * FROM TableA a, TableB b WHERE a.id = b.id;
雖然這種方法可行,但為了清晰和效能,一般還是使用顯式 JOIN 語句更好。
Q8. 什麼是 MySQL 中的連線?
答:MySQL 中的連線是根據相關列(通常是外部索引鍵)將兩個或多個表中的記錄組合在一起。透過指定如何透過這些鍵連線表,可以在單個查詢中檢索多個表中的資料。
Q9. 連線與內部連線一樣嗎?
答:是的,在 MySQL 中,JOIN 與 INNER JOIN 相同。兩者都返回被連線的兩個表中具有匹配值的記錄。如果找不到匹配,則不返回記錄。
Q10. 如何在 MySQL 中連線兩個表?
答:要在 MySQL 中連線兩個表,請結合使用 JOIN 子句和 ON 關鍵字來指定匹配條件。例如
SELECT columns FROM table1 JOIN table2 ON table1.common_column = table2.common_column;
Q11. 如何在 MySQL 中合併兩個表?
答:要在 MySQL 中合併兩個表,請使用 UNION 運算子。這會將兩個表中的行合併為一個結果。確保兩個表有相同的列數和相容的資料型別。
舉例說明:
SELECT * FROM table1 UNION SELECT * FROM table2;
注意:如果要包含所有重複行,請使用 UNION ALL 而不是 UNION。
評論留言