【MySQL】7、 關聯查詢(聯合查詢) 內連接、外連接、全外連接

第七章 關聯查詢(聯合查詢)

關聯查詢 聯合查詢

七種結果:

在這裏插入圖片描述

(1)A∩B

(2)A

(3)A - A∩B

(4)B

(5)B - A∩B

(6)A ∪ B

(7)A ∪B- A∩B 或者 (A - A∩B) ∪ (B - A∩B)

關聯查詢7種結果與關聯查詢的分類

/*
關聯查詢的結果有七種情況:
(1)A∩B
(2)A
(3)A - A ∩ B
(4)B
(5)B - A ∩ B
(6)A ∪ B
(7)A ∪ B - A ∩ B

如何實現這些結果?
1、內連接:inner join 
	(1)A∩B  A∩B A交B
2、外連接
(1)左外連:left join
	(2)A
	(3)A - A ∩ B
(2)右外連接:right join
	(4)B
	(5)B - A ∩ B
(3)全外連接:full join
	MySQL但是不直接支持全外連接,但是可以使用union(合併)結果來實現以下兩種結果
	(6)A ∪ B		用  (2)A  union(合併) (4)B
	(7)A ∪ B - A ∩ B	用  (3)A - A ∩ B  union(合併)(5)B - A ∩ B
*/

外連接查詢將查詢多個表中相關聯的行,

內連接時,返回查詢結果集合中僅是符合查詢條件和連接條件的行。有時候需要包含沒有關聯的行中數據,即返回查詢結果集合中不僅包含符合連接條件的行,還包括左表(左外連接或左連接)、右表(右外連接或右連接)或兩個邊接表(全外連接)中的所有數據行。外連接分爲左外連接或左連接和右外連接或右連

外連接分爲左外連接或左連接和右外連接或右連接:

LEFT JOIN(左連接):返回包括左表中的所有記錄和右表中連接字段相等的記錄。

RIGHT JOIN(右連接):返回包括右表中的所有記錄和左表中連接字段相等的記錄。

外連接包括了三種形式:

左外連接:LEFT JOIN 或 LEFT OUTER JOIN
右外連接:RIGHT JOIN 或 RIGHT OUTER JOIN
全外連接:FULL JOIN 或 FULL OUTER JOIN

需要注意的是 MySQL 不支持全外連接,

但是可以使用union(合併)結果來實現以下兩種結果
A ∪ B 用 A union(合併) B
A ∪ B - A ∩ B 用 A - A ∩ B union(合併)B - A ∩ B

(1)內連接

(2)外連接:左外連接、右外連接、全外連接(mysql使用union代替全外連接)

語法先上

1、內連接:實現A∩B

/*
內連接:A∩B
1、官方寫法
兩張表內連接關聯查詢
	select 字段列表
	from A表名 inner join B表名
	on 1個關聯條件
	where 其他條件等

三張表內連接關聯查詢
	select 字段列表
	from A表名 inner join B表名 inner join C表名
	on 2個關聯條件
	where 其他條件等

關聯條件的個數 = 表數 - 1
如果少了關聯條件,就會笛卡爾積的
5*3*3 45  A∩B 再交
2、另一種寫法

兩張表內連接關聯查詢
	select 字段列表
	from A表名 , B表名
	where 1個關聯條件  and 其他條件等
*/

#查詢所有員工的編號,姓名,部門編號和他所在部門的名稱
/*
select eid,ename, did,dname 
from t_employee inner join t_department;

錯誤
錯誤代碼: 1052
Column 'did' in field list is ambiguous 模糊不確定
*/
/*
select eid,ename,t_employee.did,dname 
from t_employee inner join t_department;

出現了笛卡爾積  A表的數量 * B表的數量
*/
SELECT eid,ename,t_employee.did,dname 
FROM t_employee INNER JOIN t_department
ON t_employee.did = t_department.did;

#給表名取別名
SELECT eid,ename,emp.did,dname 
FROM t_employee AS emp INNER JOIN t_department AS dept
ON emp.did = dept.did;

SELECT eid,ename,emp.did,dname 
FROM t_employee AS emp , t_department AS dept
WHERE emp.did = dept.did;

#查詢員工編號,員工姓名,員工的職位編號,職位名稱,部門編號,部門名稱
SELECT eid,ename,t_employee.`job_id`,job_name,t_employee.`did`,dname
FROM t_employee INNER JOIN t_job INNER JOIN t_department
ON t_employee.`did` = t_department.did AND t_employee.`job_id` = t_job.`job_id`;

#查詢薪資高於15000的男員工編號,員工姓名,員工的職位編號,職位名稱,部門編號,部門名稱
SELECT eid,ename,t_employee.`job_id`,job_name,t_employee.`did`,dname
FROM t_employee INNER JOIN t_job INNER JOIN t_department
ON t_employee.`did` = t_department.did AND t_employee.`job_id` = t_job.`job_id`
WHERE salary > 15000 AND gender = '男'
select 字段列表
from A表 inner join B表
on 關聯條件
where 等其他子句;

或

select 字段列表
from A表 , B表
where 關聯條件 and 等其他子句;

代碼示例:

#查詢員工的姓名和他所在的部門的名稱
#員工的姓名在t_employee
#部門的名稱在t_department
SELECT ename "員工的姓名",dname "部門名稱"
FROM t_employee INNER JOIN t_department
ON t_employee.did = t_department.did

SELECT ename "員工的姓名",dname "部門名稱"
FROM t_employee , t_department
WHERE t_employee.did = t_department.did


#查詢薪資高於20000的男員工的姓名和他所在的部門的名稱
SELECT ename "員工的姓名",dname "部門名稱"
FROM t_employee INNER JOIN t_department
ON t_employee.did = t_department.did
WHERE salary>20000 AND gender = '男'

2、左外連接

/*
左連接:
(1)A
select 字段列表
from A left join B
on 關聯條件
where 其他條件 等

(2)A -  A∩B

select 字段列表
from A left join B
on 關聯條件
where 關聯字段 is null and 其他條件 等

*/

#查詢員工的編號,姓名,部門編號,部門名稱
#包括那些沒有分配部分的員工
SELECT eid,ename,t_employee.did,dname
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did;

#查詢那些沒有分配部門的員工
SELECT eid,ename,t_employee.did,dname
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did
WHERE t_employee.did IS NULL;

#實現查詢結果是A
select 字段列表
from A表 left join B表
on 關聯條件
where 等其他子句;

#實現A -  A∩B
select 字段列表
from A表 left join B表
on 關聯條件
where 從表關聯字段 is null and 等其他子句;

代碼示例:

#查詢所有員工的姓名和他所在的部門的名稱
SELECT ename "員工的姓名",dname "部門名稱"
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did


#查詢所有沒有部門的員工
SELECT ename "員工的姓名",dname "部門名稱"
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did
WHERE t_employee.did IS NULL

3、右外連接

/*
右連接:
(1)B
select 字段列表
from A right join B
on 關聯條件
where 其他條件 等

(2)B -  A∩B

select 字段列表
from A right join B
on 關聯條件
where 關聯字段 is null and 其他條件 等

*/

#查詢員工的編號,姓名,部門編號,部門名稱
#包括那些沒有分配部分的員工
SELECT eid,ename,t_employee.did,dname
FROM t_department RIGHT JOIN t_employee
ON t_employee.did = t_department.did;

#查詢那些沒有分配部門的員工
SELECT eid,ename,t_employee.did,dname
FROM t_department RIGHT JOIN t_employee
ON t_employee.did = t_department.did
WHERE t_employee.did IS NULL;

#實現查詢結果是B
select 字段列表
from A表 right join B表
on 關聯條件
where 等其他子句;

#實現B -  A∩B
select 字段列表
from A表 right join B表
on 關聯條件
where 從表關聯字段 is null and 等其他子句;

代碼示例:

#查詢所有部門,以及所有部門下的員工信息
SELECT * 
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did

#查詢那些沒有員工屬於它的部門
SELECT * 
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did
WHERE t_employee.did IS NULL

4、用union代替全外連接 使用union實現全外連接的效果

/*
使用UNION來實現全外連接的查詢結果:
(1)A ∪ B
(2)A ∪ B - A ∩ B
迂迴成
(1)A UNION B
(2)A - A ∩ B UNION B - A ∩ B
*/

#查詢所有員工和所有部門的信息,包括那些沒有分配部門的員工和沒有安排員工的部門
SELECT * 
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.`did`

UNION

SELECT * 
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.`did`

#查詢那些沒有分配部門的員工和沒有安排員工的部門
SELECT * 
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.`did`
WHERE t_employee.did IS NULL

UNION

SELECT * 
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.`did`
WHERE t_employee.did IS NULL
#實現查詢結果是A∪B
#用左外的A,union 右外的B
select 字段列表
from A表 left join B表
on 關聯條件
where 等其他子句

union 

select 字段列表
from A表 right join B表
on 關聯條件
where 等其他子句;



#實現A∪B -  A∩B  或   (A -  A∩B) ∪ (B - A∩B)
#使用左外的 (A -  A∩B)  union 右外的(B - A∩B)
select 字段列表
from A表 left join B表
on 關聯條件
where 從表關聯字段 is null and 等其他子句

union

select 字段列表
from A表 right join B表
on 關聯條件
where 從表關聯字段 is null and 等其他子句

代碼示例:

#查詢所有員工,所有部門,包括沒有員工的部門,和沒有部門的員工
SELECT *
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did

UNION

SELECT *
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did


#查詢那些沒有部門的員工和所有沒有員工的部門

#沒有部門的員工
SELECT *
FROM t_employee LEFT JOIN t_department
ON t_employee.did = t_department.did
WHERE t_employee.did IS NULL

UNION 

#所有沒有員工的部門
SELECT *
FROM t_employee RIGHT JOIN t_department
ON t_employee.did = t_department.did
WHERE t_employee.did IS NULL

5、自連接

兩個關聯查詢的表是同一張表,通過取別名的方式來虛擬成兩張表

select 字段列表
from 表名 別名1 inner/left/right join 表名 別名2
on 別名1.關聯字段 = 別名2的關聯字段
where 其他條件

代碼示例:

#查詢員工的編號,姓名,薪資和他領導的編號,姓名,薪資
#這些數據全部在員工表中
#把t_employee表,即當做員工表,又當做領導表
#領導表是虛擬的概念,我們可以通過取別名的方式虛擬
SELECT emp.eid "員工的編號",emp.ename "員工的姓名" ,emp.salary "員工的薪資",
	mgr.eid "領導的編號" ,mgr.ename "領導的姓名",mgr.salary "領導的薪資"
FROM t_employee emp INNER JOIN t_employee mgr
#t_employee emp:如果用emp.,表示的是員工表的
#t_employee mgr:如果用mgr.,表示的是領導表的
ON emp.mid = mgr.eid

#表的別名不要加"",給列取別名,可以用"",列的別名不使用""也可以,但是要避免包含空格等特殊符號。

記錄 - 搞定Java核心技術

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章