MySQL 中各種 JOIN 的差別
MySQL 中的 JOIN 語法,可以讓我們將多張表關聯起來,但就跟斯斯有三種一樣,JOIN 也有三種,分別是。
- INNER JOIN (可以簡寫成 JOIN)。
- LEFT JOIN (有些資料庫會是 LEFT OUTER JOIN)。
- RIGHT JOIN (有些資料庫會是 RIGHT OUTER JOIN)。
那麼這三種 JOIN 的差別在哪裡?
為了方便說明,我們先假設我們有兩張表 post_tag 與 tags。
post_tag 的資料與欄位如下。
id | post_id | tag_id |
---|---|---|
1 | 1 | 43 |
2 | 2 | 16 |
3 | 2 | 56 |
tags 的資料與欄位如下。
id | name |
---|---|
1 | Ruby |
2 | Swift |
3 | TypeScript |
4 | Laravel |
5 | Ruby on Rails |
… | … |
我們先用一個查詢語法撈出所有 post_tag 的資料。
SELECT *
FROM post_tag
查詢的結果如下。
id | post_id | tag_id |
---|---|---|
1 | 1 | 43 |
2 | 2 | 16 |
3 | 2 | 56 |
我們使用 INNER JOIN 將 tags 的資料加進來。
SELECT *
FROM post_tag
JOIN tags
ON post_tag.tag_id = tags.id
查詢的結果如下。
id | post_id | tag_id | id | name |
---|---|---|---|---|
1 | 1 | 43 | 43 | Docker |
2 | 2 | 16 | 16 | Vue.js |
3 | 2 | 56 | 56 | Tailwind CSS |
我們將 JOIN 改成 LEFT JOIN。
SELECT *
FROM post_tag
LEFT JOIN tags
ON post_tag.tag_id = tags.id
我們可以看到結果沒變。
id | post_id | tag_id | id | name |
---|---|---|---|---|
1 | 1 | 43 | 43 | Docker |
2 | 2 | 16 | 16 | Vue.js |
3 | 2 | 56 | 56 | Tailwind CSS |
那如果改成 RIGHT JOIN 呢。
SELECT *
FROM post_tag
RIGHT JOIN tags
ON post_tag.tag_id = tags.id
!?
可以發現 tags 的資料全部都被放了進來。
id | post_id | tag_id | id | name |
---|---|---|---|---|
1 | 1 | 43 | 43 | Docker |
2 | 2 | 16 | 16 | Vue.js |
3 | 2 | 56 | 56 | Tailwind CSS |
(NULL) | (NULL) | (NULL) | 1 | Ruby |
(NULL) | (NULL) | (NULL) | 2 | Swift |
(NULL) | (NULL) | (NULL) | 3 | TypeScript |
(NULL) | (NULL) | (NULL) | 4 | Laravel |
… | … | … | … | … |
做個實驗,我們將 FROM 的表單與 JOIN 的表單對調。
SELECT *
FROM tags
LEFT JOIN post_tag
ON post_tag.tag_id = tags.id
查詢的結果如下。
id | name | id | post_id | tag_id |
---|---|---|---|---|
43 | Docker | 1 | 1 | 43 |
16 | Vue.js | 2 | 2 | 16 |
56 | Tailwind CSS | 3 | 2 | 56 |
1 | Ruby | (NULL) | (NULL) | (NULL) |
2 | Swift | (NULL) | (NULL) | (NULL) |
3 | TypeScript | (NULL) | (NULL) | (NULL) |
4 | Laravel | (NULL) | (NULL) | (NULL) |
… | … | … | … | … |
總結
整理每個 JOIN 的差別。
- LEFT JOIN:指的是 LEFT JOIN 左側的表單,即 table_1 表單。
SELECT * FROM table_1 LEFT JOIN table_2 ON ...
- RIGHT JOIN:指的是 RIGHT JOIN 右側的表單,即 table_2 表單。
SELECT * FROM table_1 RIGHT JOIN table_2 ON ...
- INNER JOIN 要兩張表都符合條件才會撈出來。
- LEFT JOIN 除了條件符合的,還會把 FROM 表單的資料全部撈出來。
- RIGHT JOIN 除了條件符合的,還會把 JOIN 表單的資料全部撈出來。