1. 程式人生 > 實用技巧 >MYSQL 第六課 分組查詢 連線查詢

MYSQL 第六課 分組查詢 連線查詢

分組查詢

/*
語法:

select 查詢列表
from 表
【where 篩選條件】
group by 分組的欄位(分成若干組)
【order by 排序的欄位】;

特點:
1、和分組函式一同查詢的欄位必須是group by後出現的欄位
2、篩選分為兩類:分組前篩選和分組後篩選
針對的表 位置 連線的關鍵字
分組前篩選 原始表 group by前 where

分組後篩選 group by後的結果集 group by後 having

問題1:分組函式做篩選能不能放在where後面
答:不能

問題2:where——group by——having

一般來講,能用分組前篩選的,儘量使用分組前篩選,提高效率

3、分組可以按單個欄位也可以按多個欄位(多個欄位間用逗號隔開,沒有順序要求)
4、可以搭配著排序使用

*/

#引入:查詢每個部門的員工個數

SELECT COUNT(*) FROM employees WHERE department_id=90;

#1.簡單的分組

#案例1:查詢每個工種的員工平均工資

SELECT AVG(salary),job_id
FROM employees
GROUP BY job_id;

#案例2:查詢每個位置的部門個數

SELECT COUNT(*),location_id
FROM departments
GROUP BY location_id;

#2、可以實現分組前的篩選

#案例1:查詢郵箱中包含a字元的 每個部門的最高工資

SELECT MAX(salary),department_id,email
FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id;

#案例2:查詢有獎金的每個領導手下員工的平均工資

SELECT AVG(salary),manager_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id;

#3、分組後篩選

#案例:查詢哪個部門的員工個數>5

#①查詢每個部門的員工個數

SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id;

#② 篩選剛才①結果

SELECT COUNT(*),department_id
FROM employees

GROUP BY department_id

HAVING COUNT(*)>5;


#案例2:每個工種有獎金的員工的最高工資>10000的工種編號和最高工資

SELECT job_id,MAX(salary)
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX(salary)>10000;


#案例3:領導編號>102的每個領導手下的最低工資大於5000的領導編號和最低工資

# 1 查詢每個領導手下的最低工資
# 2 領導編號>102
# 3 最低工資大於5000

SELECT manager_id,MIN(salary)
FROM employees
WHERE manager_id>102
GROUP BY manager_id
HAVING MIN(salary)>5000;

#4.新增排序

#案例:每個工種有獎金的員工的最高工資>6000的工種編號和最高工資,按最高工資升序

SELECT job_id,MAX(salary) m
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING m>6000
ORDER BY m ;

#5.按多個欄位分組

#案例:查詢每個工種每個部門的最低工資,並按最低工資降序

SELECT MIN(salary),job_id,department_id
FROM employees
GROUP BY department_id,job_id
ORDER BY MIN(salary) DESC;

#6 按表示式或函式分組

#案例 按員工姓名的長度分組,查詢每一組的員工個數,篩選員工個數大於5 的有哪些

SELECT COUNT(*),LENGTH(last_name)
FROM employees
GROUP BY LENGTH(last_name)
HAVING COUNT(*)>5;

例題

#1.查詢各job_id的員工工資的最大值,最小值,平均值,總和,並按job_id升序

SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary),job_id
FROM employees
GROUP BY job_id
ORDER BY job_id;


#2.查詢員工最高工資和最低工資的差距(DIFFERENCE)

SELECT MAX(salary)-MIN(salary) DIFFRENCE
FROM employees;

#3.查詢各個管理者手下員工的最低工資,其中最低工資不能低於6000,沒有管理者的員工不計算在內

SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id IS NOT NULL
GROUP BY manager_id
HAVING MIN(salary)>=6000;

#4.查詢所有部門的編號,員工數量和工資平均值,並按平均工資降序

SELECT department_id,COUNT(*),AVG(salary) a
FROM employees
GROUP BY department_id
ORDER BY a DESC;

#5.選擇具有各個job_id的員工人數

SELECT COUNT(*) 個數,job_id
FROM employees
GROUP BY job_id;

連線查詢

/*

含義:又稱多表查詢,當查詢的欄位來自於多個表時,就會用到連線查詢

笛卡爾乘積現象:表1 有m行,表2有n行,結果=m*n行

發生原因:沒有有效的連線條件
如何避免:新增有效的連線條件

分類:按年代分類:

sql92標準:僅僅支援內連線
sql99標準【推薦】:支援內連線+外連線(左外和右外)+交叉連線

按功能分類:
內連線:
等值連線
非等值連線
自連線
外連線:
左外連線
右外連線
全外連線

交叉連線

*/

SELECT * FROM beauty;

SELECT * FROM boys;


SELECT NAME,boyName FROM boys,beauty
WHERE beauty.boyfriend_id= boys.id;

#一、sql92標準#

1、等值連線

/*

① 多表等值連線的結果為多表的交集部分
②n表連線,至少需要n-1個連線條件
③ 多表的順序沒有要求
④一般需要為表起別名
⑤可以搭配前面介紹的所有子句使用,比如排序、分組、篩選

*/

#1、基礎

#案例1:查詢女神名和對應的男神名

SELECT NAME,boyName 
FROM boys,beauty
WHERE beauty.boyfriend_id= boys.id;

#案例2:查詢員工名和對應的部門名

SELECT last_name,department_name
FROM employees,departments
WHERE employees.`department_id`=departments.`department_id`;

#2、為表起別名

/*
①提高語句的簡潔度
②區分多個重名的欄位

注意:如果為表起了別名,則查詢的欄位就不能使用原來的表名去限定

*/
#查詢員工名、工種號、工種名

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

#3、兩個表的順序是否可以調換

#查詢員工名、工種號、工種名

SELECT last_name,department_name,commission_pct
FROM employees e,departments d
WHERE e.`department_id`=d.`department_id`
AND e.`commission_pct` IS NOT NULL;

#4、可以加篩選

#案例:查詢有獎金的員工名、部門名

SELECT last_name,department_name,commission_pct
FROM employees e,departments d
WHERE e.`department_id`=d.`department_id`
AND e.`commission_pct` IS NOT NULL;

#案例2:查詢城市名中第二個字元為o的部門名和城市名

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

#5、可以加分組

#案例1:查詢每個城市的部門個數

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

#6、可以加排序

#案例:查詢每個工種的工種名和員工的個數,並且按員工個數降序

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

#7、可以實現三表連線?

#案例:查詢員工名、部門名和所在的城市

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`
AND city LIKE 's%'

ORDER BY department_name DESC;

#2、非等值連線


#案例1:查詢員工的工資和工資級別

SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.`lowest_sal` AND g.`highest_sal`
AND g.`grade_level`='A';

/*
select salary,employee_id from employees;


select * from job_grades;


CREATE TABLE job_grades
(grade_level VARCHAR(3),
lowest_sal int,
highest_sal int);

INSERT INTO job_grades
VALUES ('A', 1000, 2999);

INSERT INTO job_grades
VALUES ('B', 3000, 5999);

INSERT INTO job_grades
VALUES('C', 6000, 9999);

INSERT INTO job_grades
VALUES('D', 10000, 14999);

INSERT INTO job_grades
VALUES('E', 15000, 24999);

INSERT INTO job_grades
VALUES('F', 25000, 40000);

*/

#3、自連線

#案例:查詢 員工名和上級的名稱 (找了兩遍)

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`;

#1.顯示所有員工的姓名,部門號和部門名稱。

USE myemployees;

SELECT last_name,d.department_id,department_name
FROM employees e,departments d
WHERE e.`department_id` = d.`department_id`;


#2.查詢90號部門員工的job_id和90號部門的location_id

SELECT job_id,location_id
FROM employees e,departments d
WHERE e.`department_id`=d.`department_id`
AND e.`department_id`=90;

#3. 選擇所有有獎金的員工的
last_name , department_name , location_id , city

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

#4.選擇city在Toronto工作的員工的
last_name , job_id , department_id , department_name

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

#5.查詢每個工種、每個部門的部門名、工種名和最低工資

SELECT department_name,job_title,MIN(salary) 最低工資
FROM employees e,departments d,jobs j
WHERE e.`department_id`=d.`department_id`
AND e.`job_id`=j.`job_id`
GROUP BY department_name,job_title;

#6.查詢每個國家下的部門個數大於2的國家編號

SELECT country_id,COUNT(*) 部門個數
FROM departments d,locations l
WHERE d.`location_id`=l.`location_id`
GROUP BY country_id
HAVING 部門個數>2;

#7、選擇指定員工的姓名,員工號,以及他的管理者的姓名和員工號,結果類似於下面的格式
employees Emp# manager Mgr#
kochhar 101 king 100

SELECT e.last_name employees,e.employee_id "Emp#",m.last_name manager,m.employee_id "Mgr#"
FROM employees e,employees m
WHERE e.manager_id = m.employee_id
AND e.last_name='kochhar';