SQL語句(四)聯表查詢


一、關聯查詢的分類

按年代分

sql92:僅僅支持內連接
sql99【推薦】:支持內連接+外連接(左外,右外)+交叉連接

按功能分

  • 內連接
    • 等值連接
    • 非等值連接
    • 自連接
  • 外連接
    • 左外連接
    • 右外連接
    • 全外連接
  • 交叉連接

二、sql92語法的連接

語法

SELECT	查詢列表
FROM 	待鏈接的多個表
WHERE 	連接條件 [和篩選條件]

這里的連接條件寫字段相等關系,如e.department_id = d.id

1. 簡單應用

查詢員工名和對應的部門名

SELECT 	last_name 員工名,department_name 部門名
FROM 	employees, departments
WHERE 	employees.department_id=departments.department_id;
# 連接條件為employees.department_id=departments.department_id

2. 為表起別名

SELECT 	查詢列表
FROM 	表名 AS 別名, ...
WHERE 	連接條件等

查詢員工名工種號工種名

SELECT 	last_name,e.job_id,job_title
FROM 	employees AS e, jobs AS j
WHERE 	e.job_id = j.job_id;

由於兩個表中都有job_id這個字段,所以在SELECT中需要指明是哪張表

3. 加入篩選

查詢有獎金的 員工名部門名

SELECT	e.last_name, d.department_name
FROM	employees e, departments d
WHERE 	e.department_id = d.department_id
		AND	e.commission_pct IS NOT NULL; <--加入的篩選條件

查詢位於的城市的城市名中第二個字符為o部門名城市名

SELECT city,department_name
FROM locations l,departments d
WHERE d.location_id=l.location_id
		AND city LIKE '_o%';

4. 加入分組

查詢每個城市部門個數

SELECT 	 city,COUNT(*) 部門個數
FROM 	 locations l,departments d
WHERE 	 l.location_id=d.location_id
GROUP BY city

查詢每個工種工種名員工個數,並按員工個數降序

SELECT 	job_title,COUNT(*) 員工個數
FROM 	jobs j,employees e
WHERE 	j.job_id=e.job_id
GROUP BY job_title
ORDER BY 員工個數 DESC;

5. 三表連接

和兩表連接是基本相同的,在WHERE語句中加入一個連接條件即可

獲取所有員工的員工名部門名所在城市

SELECT last_name, department_name, city
FROM employees e, departments d, locations l
WHERE e.department_id = d.department_id
		AND d.location_id = l.location_id;

6. 非等值連接

查詢員工的工資工資級別

job_grades表:

SELECT 	salary, grade_level
FROM 	employees e, job_grades j
WHERE 	e.salary >= j.lowest_sal AND e.salary <= j.highest_sal;

7. 自連接

查詢員工名及其對應上級的名稱

SELECT 	e.last_name 員工,m.last_name 上級
FROM 	employees e, employees m
WHERE 	e.manager_id=m.employee_id;

三、sql99語法的連接

SELECT 查詢列表
FROM 表1別名 
	【連接類型】 join 表2 別名 
	on 連接條件
where xxx

連接類型分類

  • 內連接:inner
    sql92等值連接等效
  • 外連接:
    • 左外:left [outer]
    • 右外:right [outer]
    • 全外:full [outer]
  • 交叉連接:cross

1. 內連接(INNER JOIN)

獲取所有的員工名和其對應的部門名

SELECT e.last_name, d.department_name
FROM employees e INNER JOIN departments d
		ON e.department_id = d.department_id;

查詢部門個數>3城市名部門個數

SELECT city, COUNT(1) 部門個數
FROM departments d INNER JOIN locations l
		ON d.location_id = l.location_id
GROUP BY city
HAVING 部門個數 > 3;

查詢員工名、部門名、工種名,並按部門名排序【三表連接

SELECT last_name, department_name, job_title
FROM employees e INNER JOIN departments d 
		ON e.department_id = d.department_id
	INNER JOIN jobs j
		ON e.job_id = j.job_id
ORDER BY department_name DESC;

查詢員工的工資級別【非等值連接

SELECT last_name, salary, grade_level
FROM employees e INNER JOIN job_grades j
	ON e.salary BETWEEN j.lowest_sal AND j.highest_sal
ORDER BY salary;

查詢員工名即其對應的上級名【自連接

SELECT e.last_name 員工名, m.last_name 上級名
FROM employees e INNER JOIN employees m
	ON e.manager_id = m.employee_id;

由上面的例子可以看出,使用sql99的內連接(INNER JOIN)即可實現sql92的所有連接操作了。

2. 外連接

作用:查詢一個表有另一個表沒有的記錄

先使用girls.sql生成對應的數據,對應的文件可以在https://www.bilibili.com/video/BV12b411K7Zu?from=search&seid=2415880702283399133 這個b站視頻的評論區中找到。

此時我們可以獲得如下幾張表:

然后我們可以分別使用內連接和外連接分別連接beautyboys這兩張表,查看結果的差異:

內連接:

SELECT *
FROM beauty b INNER JOIN boys y
	ON b.boyfriend_id = y.id;

外連接(左外):

SELECT *
FROM beauty b LEFT JOIN boys y
	ON b.boyfriend_id = y.id;

可以發現,當左表(即beauty表)的boyfriend_id字段找不到boys表中對應的id進行連接時,它也仍會保留這一記錄,而右表(即boys表)的記錄則全部設置為Null

一句話來說,就是左表的數據不管是否滿足連接條件,都至少會保留在最終查詢集的一條記錄之中

查找男朋友不在男神表的女神名【左外連接】:

SELECT `name`, boyName
FROM beauty b LEFT JOIN boys y
	ON b.boyfriend_id = y.id
WHERE y.id IS NULL;

右外連接

SELECT `name`, boyName
FROM boys y RIGHT JOIN beauty b
	ON b.boyfriend_id=y.id
WHERE y.id IS NULL;

查詢沒有聯系女神男生

SELECT `name`, boyName
FROM beauty b RIGHT JOIN boys y
	ON b.boyfriend_id=y.id
WHERE b.id IS NULL;

查詢哪個部門 沒有員工

SELECT department_name, COUNT(*)
FROM departments d LEFT JOIN employees e
	ON d.department_id = e.department_id
GROUP BY department_name
HAVING COUNT(*)=0;

3. 交叉連接

SELECT b.`name`, y.boyName
FROM beauty b CROSS JOIN boys y;

在這里插入圖片描述
即返回笛卡爾積(即所有組合的可能),左表數據為m條,右表數據為n條,最終查詢集數據為m * n


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM