1. 程式人生 > >(四)MySQL基礎——分組查詢、連線查詢

(四)MySQL基礎——分組查詢、連線查詢

分組查詢

GROUP BY語法:

  SELECT  分組函式  ,列(要求出現在GROUP BY的後面)FROM  表  【WHERE  篩選條件】GROUP BY  分組的列表

【ORDER  BY  子句】

注意:

查詢列表比較特殊,要求是分組函式和GROUP BY 後出現的欄位

分類:

分組查詢中的篩選條件分為兩類:分組前篩選分組後篩選。兩類篩選的資料來源是不一樣的,前者對原始表進行篩選後者對分組後的結果集進行篩選;因此這些篩選條件出現的位置也不一樣,前者在GROUP BY子句的前面後者在GROUP BY 子句的後面;並且用到的關鍵字也不一樣,前者用的是WHERE

,而後者用到了HAVING這一關鍵字。

分組函式做條件,肯定是放在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;