(四)MySQL基礎——分組查詢、連線查詢
分組查詢
GROUP BY語法:
SELECT 分組函式 ,列(要求出現在GROUP BY的後面)FROM 表 【WHERE 篩選條件】GROUP BY 分組的列表
【ORDER BY 子句】
注意:
查詢列表比較特殊,要求是分組函式和GROUP BY 後出現的欄位
分類:
分組查詢中的篩選條件分為兩類:分組前篩選 和 分組後篩選。兩類篩選的資料來源是不一樣的,前者對原始表進行篩選,後者對分組後的結果集進行篩選;因此這些篩選條件出現的位置也不一樣,前者在GROUP BY子句的前面,後者在GROUP BY 子句的後面;並且用到的關鍵字也不一樣,前者用的是WHERE
分組函式做條件,肯定是放在HAVING子句中。
能用分組前篩選的,就優先考慮使用分組前篩選。
GROUP BY子句支援單個欄位分組,多個欄位分組(多個欄位之間用逗號隔開,沒有順序要求),表示式或函式(用的較少),也可以新增排序(排序放在整個分組查詢的最後)
按函式分組查詢的一些例子:
-- 案例1,:查詢每個工種的最高工資 【每個】 SELECT MAX(salary),job_id FROM employees GROUP BY job_id; -- 案例2:查詢每個位置上的部門個數 【每個】 SELECT COUNT(*),location_id FROM departments GROUP BY location_id; -- 案例3:查詢郵箱中包含a字元的,每個部門的平均工資 【每個】 SELECT AVG(salary),department_id FROM employees WHERE email LIKE '%a%' GROUP BY department_id; -- 案例4:查詢有獎金的每個領導手下員工的最高工資 【新增分組前的篩選】 SELECT MAX(salary), manager_id FROM employees WHERE commission_pct IS NOT NULL GROUP BY manager_id; -- 案例5:查詢哪個部門的員工數>2 【新增分組後的篩選】 -- ①查詢每個部門的員工個數 SELECT COUNT(*),department_id FROM employees GROUP BY department_id -- ②根據①的結果進行篩選,查詢哪個部門的員工個數>2 SELECT COUNT(*),department_id FROM employees GROUP BY department_id HAVING COUNT(*)>2;
GROUP BY 和 HAVING 後面是支援放別名的,但是WHERE後面不支援,且這些功能在Oracle中也是有限制的,在MySQL中才這樣處理。
按多個欄位分組查詢的一些例子:
-- 案例1、查詢每個部門每個工種的員工的平均工資
SELECT department_id,AVG(salary),job_id FROM employees GROUP BY department_id,job_id;
連線查詢
含義:
連線查詢又叫多表查詢,當查詢的欄位來自於多個表時,就會用到連線查詢
笛卡爾乘積現象:表1有m行,表2有n行,結果為m*n行
發生原因:沒有有效的連線條件
如何避免:新增有效的連線條件
分類:
1、按年代分類:
sql92標準:僅僅支援內連線
sql99標準【推薦使用】:支援內連線+外連線(僅支援左外連線+右外連線)+交叉連線
2、按功能分類:
內連線:等值連線、非等值連線、自連線
外連線:左外連線、右外連線、全外連線
交叉連線
一、sql92標準
等值連線的特點:
多表等值連線的結果為多表的交集部分;N表連線,至少需要N-1個連線條件;多表的順序沒有要求;一般需要為表取別名;可以搭配前面介紹的所有查詢子句使用,比如排序、分組、篩選。
-- 案例1、查詢員工名和對應的部門名 【等值連線】
SELECT last_name,department_name FROM employees,departments WHERE departments.department_id=employees.department_id;
-- 案例2、查詢有獎金的員工名、部門名 【等值連線+篩選】
SELECT last_name,department_name,commission_pct FROM employees,departments WHERE employees.commission_pct IS NOT NULL AND empartments.department_id = employees.department_id;
-- 案例3、查詢每個城市的部門個數 【等值連線+分組】
SELECT COUNT(*),city FROM departments,locations WHERE department.location_id=locations.location_id GROUP BY city;
-- 案例4、查詢每個工種的工種名和員工的個數,並且按員工個數降序 【等值連線+排序】
SELECT COUNT(*),job_title FROM employees,jobs WHERE employees.job_id=jobs.job_id GROUP BY job_title ORDER BY COUNT(*) DESC;
為表起別名:可以提高語句的簡潔度,區分多個重名的欄位。如果為表起了別名,則查詢的欄位不能使用原來的表名去限定了。
非等值連線:
-- 案例1、查詢員工的工資和工資級別 【非等值連線+篩選】
SELECT salary,grade_level FROM employees e ,job_gardes g WHERE salary BETWEEN g.lowest_sal AND g.highest_sal AND g.grade_level='A';
自連線:
-- 案例1、查詢員工名和上級的名稱
SELECT e.employee_id,e.last_name,m.employee_id,m.last_name FROM employees e ,employees m WHERE e.manager_id=m.employee_id;