MySQL 学习笔记(15)— 连接查询(内连接、左外连接、右外连接、全外连接、交叉连接、自然连接等)
本文參考:https://gitbook.cn/gitchat/column/undefined/topic/5db92b68a9c3a53bc3800eff
SQL 支持的連接查詢包括內連接、外連接、交叉連接、自然連接以及自連接等。其中,外連接又可以分為左外連接、右外連接以及全外連接。
另外,連接查詢中的 ON 子句與 WHERE 子句類似,可以支持各種條件運算符( = 、 >= 、 != 、 BETWEEN 等)。但最常用的是等值連接( = ),我們主要介紹這種條件的連接查詢。
假設我們有 3 張表, department 表 和 job 表內容分別為:
employee 表內容為:
1. 內連接
內連接(Inner Join)返回兩個表中滿足連接條件的數據;使用關鍵字 INNER JOIN 表示,也可以簡寫成 JOIN。內連接的原理如下圖所示(基于兩個表的 id 進行等值連接):
其中,id = 1 和 id = 3 是兩個表中匹配的數據,因此內連接返回了這 2 行記錄。
例如:要查詢所有員工的名稱和所屬的部門名稱,就需要查詢 employee 表和 department 表:
select e.emp_name, d.dept_name
from employee as e
join department as d on (d.dept_id = e.dept_id)
首先, JOIN 表示需要連接員工表和部門表; ON 子句用于指定連接條件,同樣是使用員工表中的部門編號和部門表中的編號進行相等連接。
2. 左外連接
左外連接(Left Outer Join)首先返回左表中所有的數據;對于右表,返回滿足連接條件的數據;如果沒有相應的數據就返回空值。左外連接使用關鍵字 LEFT OUTER JOIN 表示,也可以簡寫成 LEFT JOIN 。左外連接的原理如下圖所示(基于兩個表的 id 進行連接):
其中,id = 2 的數據在 table1 中存在,在 table2 中不存在;左外連接仍然會返回左表中的該記錄,而對于 table2 中的價格(price),返回的是空值。
假設我們想要查看所有的部門及其員工信息。考慮到某些部門可能還沒有入職員工,如果使用內連接,則無法顯示這些部門;因此使用左外連接:
select d.dept_name , e.emp_name
from department as d
left join employee as e on (d.dept_id = e.dept_id)
其中, LEFT JOIN 表示左外連接;連接條件仍然是兩個表中的部門編號是否相等。查詢結果如下所示:
3. 右外連接
右外連接(Right Outer Join)首先返回右表中所有的數據;對于左表,返回滿足連接條件的數據,如果沒有相應的數據就返回空值。右外連接使用關鍵字 RIGHT OUTER JOIN 表示,也可以簡寫成 RIGHT JOIN 。右外連接的原理如下圖所示(基于兩個表的 id 進行連接):
其中,id = 5 的數據在 table2 中存在,在 table1 中不存在;右外連接仍然會返回右表中的該記錄,而對于 table1 中的名稱(name),返回的是空值。簡而言之:
table1 RIGHT JOIN table2
等價于:
table2 LEFT JOIN table1
右外連接和左外連接可以相互轉換。
select d.dept_name , e.emp_name
from employee as e
right join department as d on (d.dept_id = e.dept_id)
order by emp_name
注意交換兩個表的位置。以上語句的結果與左外連接的結果相同。
4. 全外連接
全外連接(Full Outer Join)等價于左外連接加上右外連接,同時返回左表和右表中所有的數據;對于兩個表中不滿足連接條件的數據返回空值。全外連接使用關鍵字 FULL OUTER JOIN 表示,也可以簡寫成 FULL JOIN 。全外連接的原理如下圖所示(基于兩個表的 id 進行連接):
結果中包含了所有的 id,然后對于兩個表中不滿足連接條件的數據(id = 2 和 id = 5),分別在相應的字段中返回了空值。
假如我們想要查看所有的部門和員工信息。同時考慮到某些部門可能還沒有員工,而且某些員工可能還沒有分配部門,可以使用全外連接:
-- Oracle、SQL Server 以及 PostgreSQL 實現
SELECT d.dept_id, e.dept_id, d.dept_name, e.emp_nameFROM department dFULL JOIN employee e ON (e.dept_id = d.dept_id);
MySQL 不支持全外連接。
5. 交叉連接
交叉連接也稱為笛卡爾積(Cartesian Product),使用關鍵字 CROSS JOIN 表示。兩個表的交叉連接相當于一個表的所有行和另一個表的所有行兩兩組合,結果的數量為兩個表的行數相乘。如果第一個表有 1000 行,第二個表有 2000 行,它們的交叉連接將會產生 2000000 行數據。
交叉連接可能會導致查詢結果的數量急劇增長,從而引起性能問題;通常應該使用連接條件進行過濾,避免產生交叉連接。
交叉連接的原理如下圖所示(基于兩個表的 id 進行連接):
結果總共包含 9 條記錄。交叉連接一般使用較少。
6. 自然連接
對于連接查詢,如果滿足以下條件,可以使用 USING 替代 ON 簡化連接條件的輸入:
- 連接條件是等值連接;
- 兩個表中的連接字段必須名稱相同,類型也相同。
針對上文中的內連接查詢示例,可以使用 USING 簡化如下:
-- Oracle、MySQL 以及 PostgreSQL 實現
SELECT dept_id, d.dept_name, e.emp_nameFROM employee eJOIN department d USING (dept_id);
其中, USING 表示使用兩個表中的公共字段( dept_id )進行等值連接。查詢語句中的公共字段不需要添加表名限定。該語句的結果與上文中的內連接查詢示例相同。
SQL Server 不支持 USING 語法, 不支持自然連接。
進一步來說,如果等值連接條件中包含了兩個表中所有同名同類型的字段,可以使用自然連接( NATURAL JOIN )。例如,員工表和部門表只擁有 1 個同名字段 dept_id ;因此上面的示例可以使用自然連接表示:
-- Oracle、MySQL 以及 PostgreSQL 實現
SELECT dept_id, d.dept_name, e.emp_nameFROM employee e
NATURAL JOIN department d;
NATURAL JOIN 表示自然連接,這種情況下可以簡化查詢的輸入。該語句的結果與上文中的內連接查詢示例相同。
總結
以上是生活随笔為你收集整理的MySQL 学习笔记(15)— 连接查询(内连接、左外连接、右外连接、全外连接、交叉连接、自然连接等)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL 学习笔记(14)— 数据库设
- 下一篇: 美女与野兽的作者是谁啊?