當我們查詢的數據來源於多張表的時候,我們需要用到連接查詢,連接查詢使用率非常高,是務必掌握的。聯結( JOIN )就是將其他表中的列添加過來,進行“添加列”的集合運算。聯結大體上分爲內聯結和外聯結兩種。
笛卡爾積
笛卡爾積( 交叉聯結:CROSS JOIN)簡單點理解:有兩個集合A和B,笛卡爾積表示A集合中的元素和B集合中的元素任意相互關聯產生的所有可能的結果。
假如A中有m個元素,B中有n個元素,A、B笛卡爾積產生的結果有m*n個結果,相當於循環遍歷兩個集合中的元素,任意組合。
java僞代碼表示如下:
for(Object eleA : A){
for(Object eleB : B){
System.out.print(eleA+","+eleB);
}
}
過程:拿A集合中的第1行,去匹配集合B中所有的行,然後再拿集合A中的第2行,去匹配集合B中所有的行,最後結果數量爲m*n。
笛卡爾積語法:
select 字段 from 表1,表2[,表N];
或者
select 字段 from 表1 join 表2 [join 表N];
內聯結
內聯結也稱爲INNER JOIN,相當於在笛卡爾積的基礎上添加了內聯結的條件,當沒有聯結條件是便上升爲笛卡爾積。
java僞代碼表示如下:
for(Object eleA : A){
for(Object eleB : B){
if (聯結條件是否爲true)
System.out.print(eleA+","+eleB);
}
}
INNER JOIN語法:
select 字段 from 表1 join 表2 ON 聯結條件;
或者
select 字段 from 表1 inner join 表2 ON 聯結條件;
或者
select 字段 from 表1,表2 [where 關聯條件];
內聯接建議使用第三種表示方法,更加簡潔。
內聯結查詢如下:
mysql> SELECT
t1.emp_name,
t2.team_name
FROM
t_employee t1
INNER JOIN
t_team t2
ON
t1.team_id = t2.id;
+---------------+-----------+
| emp_name | team_name |
+---------------+-----------+
| Lw中 | 程序員組 |
| 張三 | 測試組 |
| 李四 | java組 |
+---------------+-----------+
3 rows in set (0.00 sec)
示例1:有聯結條件
select
t1.emp_name,t2.team_name
from
t_employee as t1 inner join t_team as t2
on
t1.team_id = t2.id;
示例2:無聯結條件
select
t1.emp_name,t2.team_name
from t_employee as t1 inner join t_team as t2;
示例3:組合條件查詢
select
t1.emp_name,t2.team_name
from
t_employee as t1, t_team as t2
where
t1.team_id = t2.id and t2.team_name = '底層程序員組';
外聯結
內聯結也稱爲OUTER JOIN,外連接涉及到2個表,分爲:主表和從表,要查詢的信息主要來自於哪個表,誰就是主表。
外聯結查詢結果會輸出主表中所有記錄。如果從表中有和它匹配的,則顯示匹配的值,這部分相當於內聯結;如果從表中沒有和它匹配的,則顯示null。
最終:外聯結查詢結果 = 內聯結的結果 + 主表中有的而內聯結結果中沒有的記錄。
外聯結分爲2種:
左外聯結:使用left join關鍵字,left join左邊的是主表。
右外聯結:使用right join關鍵字,right join右邊的是主表。
左聯結
左外聯結:使用left join關鍵字,left join左邊的是主表。
LEFT JOIN語法:
select 列 from 主表 left join 從表 on 連接條件;
示例:
mysql> SELECT
t1.emp_name,
t2.team_name
FROM
t_employee t1
LEFT JOIN
t_team t2
ON
t1.team_id = t2.id;
+---------------+-----------+
| emp_name | team_name |
+---------------+-----------+
| Lw中 | 程序員組 |
| 張三 | 測試組 |
| 李四 | java組 |
| 王五 | NULL |
| 趙六 | NULL |
+---------------+-----------+
5 rows in set (0.00 sec)
右聯結
右外聯結:使用right join關鍵字,right join右邊的是主表。
RIGHT JOIN語法:
select 列 from 從表 right join 主表 on 連接條件;
示例:
mysql> SELECT
t2.team_name,
t1.emp_name
FROM
t_team t2
RIGHT JOIN
t_employee t1
ON
t1.team_id = t2.id;
+-----------+---------------+
| team_name | emp_name |
+-----------+---------------+
| 程序員組 | Lw中 |
| 測試組 | 張三 |
| java組 | 李四 |
| NULL | 王五 |
| NULL | 趙六 |
+-----------+---------------+
5 rows in set (0.00 sec)
全聯結
全聯結:使用full join關鍵字,把左右兩張表的數據都查詢出來,不管匹配與否。
FULL JOIN語法如下:
select 列 from 表1 full join 表2 on 連接條件;
示例:
mysql> SELECT
t2.team_name,
t1.emp_name
FROM
t_team t2
FULL JOIN
t_employee t1
ON
t1.team_id = t2.id;
+-----------+---------------+
| team_name | emp_name |
+-----------+---------------+
| 程序員組 | Lw中 |
| 測試組 | 張三 |
| java組 | 李四 |
| NULL | 王五 |
| 設計組 | NULL |
| NULL | 趙六 |
| 研發組 | NULL |
| NULL | 小明 |
+-----------+---------------+
8 rows in set (0.00 sec)
三張以上的表聯結
通常聯結只涉及 2 張表,但有時也會出現必須同時聯結 3 張以上的表
的情況,原則上聯結表的數量並沒有限制。
三表以上聯結語法:
select 列 from 表1 inner join 表2 on 連接條件 inner join 表3 on 聯結條件 inner join ...;
假設現在有三張表,departments、dept_emp、employees,需要查找所有員工的last_name和first_name以及對應的dept_name
departments表
CREATE TABLE `departments` (
`dept_no` char(4) NOT NULL,
`dept_name` varchar(40) NOT NULL,
PRIMARY KEY (`dept_no`));
dept_emp表
CREATE TABLE `dept_emp`
(`emp_no` int(11) NOT NULL comment '所有的員工編號',
`dept_no` char(4) NOT NULL comment '部門編號',
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`dept_no`));
employees表
CREATE TABLE `employees` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` char(1) NOT NULL,
`hire_date` date NOT NULL,
PRIMARY KEY (`emp_no`));
查詢語句如下:
select
e.last_name, e.first_name, d.dept_name
from
employees e
inner join
dept_emp de on e.emp_no = de.emp_no
inner join
departments d on de.dept_no = d.dept_no;