上次講座我們聊過 SQL 裡有哪些 JOIN 類型。今天我們要更深入聊聊 INNER JOIN。
INNER JOIN 就是關聯式資料庫裡合併資料的一種方式,讓你可以從兩個表格裡抓出「符合你設定條件」的那些行。也就是說,INNER JOIN 只會回傳兩個表格交集的部分,其他都不管。
想像一下,你有兩個盒子。一個放著學生的卡片,另一個放著學生註冊課程的卡片。你想知道哪些學生報名了哪些課程。如果沒對應(比如某個學生沒報名任何課程),這些資料我們暫時不管。這種情境就超適合用 INNER JOIN。
INNER JOIN 語法
語法很直白——你指定兩個想合併的表格,然後用 ON 關鍵字設定合併條件。
SELECT 欄位們
FROM 表格1 INNER JOIN 表格2
ON 表格1.欄位 = 表格2.欄位;
表格1和表格2—— 就是你要合併的兩個表。欄位—— 用來比對的欄位。ON後面的條件就是規定兩個表格的哪些行要配對。
INNER JOIN 使用範例
接下來的例子我們會用到兩個表:
表 students —— 學生資料
| student_id | name | age |
|---|---|---|
| 1 | Otto | 20 |
| 2 | Anna | 22 |
| 3 | Peter | 19 |
| 4 | Dia | 21 |
表 enrollments —— 課程註冊資料
| enrollment_id | student_id | course_id |
|---|---|---|
| 101 | 1 | 501 |
| 102 | 2 | 502 |
| 103 | 2 | 503 |
| 104 | 3 | 504 |
注意,學生 Dia(student_id = 4)沒有註冊任何課程。
範例 1:查詢學生和他們的課程
我們想知道哪些學生有報名課程。這就是 INNER JOIN 的經典用法。我們只關心 students 和 enrollments 這兩個表格裡 student_id 有對上的資料。
SELECT students.name, enrollments.course_id
FROM students INNER JOIN enrollments
ON students.student_id = enrollments.student_id;
結果:
| name | course_id |
|---|---|
| Otto | 501 |
| Anna | 502 |
| Anna | 503 |
| Peter | 504 |
你看到了嗎?INNER JOIN 只回傳有註冊課程的學生。Dia 沒有報名任何課程,所以沒出現在結果裡。
範例 2:查詢訂單和客戶
再來看另一個例子。假設我們有 orders(訂單)和 customers(客戶)兩個表。我們想查詢所有訂單以及對應的客戶名字。
表 orders
| order_id | customer_id | amount |
|---|---|---|
| 1 | 101 | 500 |
| 2 | 102 | 300 |
| 3 | 103 | 700 |
表 customers
| customer_id | name |
|---|---|
| 101 | Otto |
| 102 | Anna |
| 104 | Peter |
任務:我們要用 customer_id 把 orders 和 customers 合併,只回傳有對應客戶的訂單。
SELECT orders.order_id, customers.name, orders.amount
FROM orders INNER JOIN customers
ON orders.customer_id = customers.customer_id;
結果:
| order_id | name | amount |
|---|---|---|
| 1 | Otto | 500 |
| 2 | Anna | 300 |
注意,order_id = 3 的訂單沒出現在結果裡,因為 customer_id = 103 在 customers 表裡根本不存在。
INNER JOIN 怎麼幫你合併表格(還有可能踩到的雷)
INNER JOIN 幾乎是你做任何關聯式資料庫專案都會用到的主力工具。就像工具箱裡的板手一樣:你可以不用它,但會很難搞定事情。舉例來說:
- 做報表時,要把多個表格的資料合併起來。
- 做分析時,要把事實表和維度表連起來(像是銷售和客戶)。
- 整合外部系統的資料。
新手最常犯的錯就是忘了 ON 或是條件寫錯。如果你沒設對條件,結果會變成兩個表的 笛卡兒積——可能會有成千上萬行,完全沒意義。
錯誤範例:
這個例子沒有合併條件,所以查詢會產生兩個表所有行的組合(這絕對不是你想要的):
SELECT students.name, enrollments.course_id
FROM students, enrollments; -- 錯誤:沒有合併條件!
結果會超亂:每個 students 的行都會跟每個 enrollments 的行配對一次。
GO TO FULL VERSION