导入这三个sql文件,就能跟着操作啦
https://cloud.189.cn/t/NFF7NzyyEZNv (访问码:rtu8)
里面有3张表。分别一次性执行就能创建成功啦。
# 三、分组函数、分组查询、连接查询(多表查询)
-- 3.1.1 分组函数
/*
功能:用作统计使用,又称为聚合函数或统计函数或组函数
分类:
sum 求和、avg 平均值、max 最大值 、min 最小值 、count 计算个数
特点:
1、sum、avg一般用于处理数值型
max、min、count可以处理任何类型
2、以上分组函数都忽略null值
3、可以和distinct搭配实现去重的运算
4、count函数的单独介绍
一般使用count(*)用作统计行数
5、和分组函数一同查询的字段要求是group by后的字段
*/
-- 1.简单使用
SELECT SUM(salary) FROM employees;
SELECT AVG(salary) FROM employees;
SELECT MIN(salary) FROM employees;
SELECT MAX(salary) FROM employees;
SELECT COUNT(salary) FROM employees;
SELECT SUM(salary) 和,AVG(salary) 平均,MAX(salary) 最高,MIN(salary) 最低,COUNT(salary) 个数
FROM employees;
-- 2.count函数的详细介绍
SELECT COUNT(salary) FROM employees;
SELECT * FROM employees;
SELECT COUNT(*) FROM employees;
SELECT COUNT(1) FROM employees;
效率:
MYISAM存储引擎下 ,COUNT(*)的效率高
INNODB存储引擎下,COUNT(*)和COUNT(1)的效率差不多,比COUNT(字段)要高一些
-- 3. 和分组函数一同查询的字段有限制
SELECT AVG(salary),employee_id FROM employees;
-- 4.查询公司员工工资的最大值,最小值,平均值,总和
SELECT MAX(salary) 最大值,MIN(salary) 最小值,AVG(salary) 平均值,SUM(salary) 和
FROM employees;
-- 5.#2.查询员工表中的最大入职时间和最小入职时间的相差天数 (DIFFRENCE)
SELECT MAX(hiredate) 最大,MIN(hiredate) 最小,(MAX(hiredate)-MIN(hiredate))/1000/3600/24 DIFFRENCE
FROM employees;
## 推荐下面这种
SELECT DATEDIFF(MAX(hiredate),MIN(hiredate)) DIFFRENCE
FROM employees;
-- 3.1.2 分组查询
/*
语法:
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、可以搭配着排序使用
*/
-- 1.查询每个部门的员工个数
SELECT department_id 部门,COUNT(*) 员工个数
FROM employees GROUP BY department_id;
-- 2.查询每个工种的员工平均工资
SELECT job_id, AVG(salary) 平均工资 FROM employees
GROUP BY job_id;
-- 3.查询每个位置的部门个数
SELECT COUNT(department_id) 部门个数, location_id FROM departments
GROUP BY location_id;
-- 可以实现分组前的筛选
-- 4.查询邮箱中包含a字符的 每个部门的最高工资
SELECT department_id,MAX(salary) 最高工资 FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id;
-- 5.查询有奖金的每个领导手下员工的平均工资
SELECT manager_id, AVG(salary) FROM employees
WHERE commission_pct is not NULL
GROUP BY manager_id;
-- 分组后筛选
-- 6.查询哪个部门的员工个数>5
SELECT department_id, COUNT(*) FROM employees
GROUP BY department_id
HAVING COUNT(*)> 5;
#分步骤进行: 首先查询每个部门的员工个数
SELECT COUNT(*),department_id
FROM employees
GROUP BY department_id;
#接着,查询出>5的部门
SELECT COUNT(*),department_id FROM employees
GROUP BY department_id
HAVING COUNT(*)>5;
-- 7、每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
SELECT job_id, MAX(salary) 最高工资 FROM employees
WHERE commission_pct is NOT NULL
GROUP BY job_id
HAVING MAX(salary)> 12000;
-- 8.领导编号>102的每个领导手下的最低工资大于5000的领导编号和最低工资
SELECT manager_id, MIN(salary) FROM employees
WHERE manager_id > 102
GROUP BY manager_id
HAVING MIN(salary) >5000;
-- 9.每个工种有奖金的员工的最高工资>6000的工种编号和最高工资,按最高工资升序
SELECT job_id, MAX(salary) 最高工资 FROM employees
WHERE commission_pct is NOT NULL
GROUP BY job_id
HAVING MAX(salary)>6000
ORDER BY MAX(salary) ASC;
-- 10.查询每个工种每个部门的最低工资,并按最低工资降序
SELECT job_id, department_id, MIN(salary) 最低工资 FROM employees
GROUP BY job_id, department_id
ORDER BY MIN(salary) DESC;
-- 11.查询各job_id的员工工资的最大值,最小值,平均值,总和,并按job_id升序
SELECT MAX(salary), MIN(salary), AVG(salary), SUM(salary) FROM employees
GROUP BY job_id
ORDER BY job_id;
-- 12.查询员工最高工资和最低工资的差距(DIFFERENCE)
SELECT MAX(salary)-MIN(salary) as DIFFERENDE
FROM employees;
-- 13.查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计算在内
SELECT MIN(salary),manager_id
FROM employees
WHERE manager_id IS NOT NULL
GROUP BY manager_id
HAVING MIN(salary)>=6000;
-- 14.查询所有部门的编号,员工数量和工资平均值,并按平均工资降序
SELECT department_id, COUNT(*), AVG(salary) FROM employees
GROUP BY department_id
ORDER BY AVG(salary) DESC;
-- 15.选择具有各个job_id的员工人数
SELECT COUNT(*) 个数, job_id
FROM employees
GROUP BY job_id;
-- 3.1.3 连接查询 /又称 多表查询
/*
含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象:表1 有m行,表2有n行,结果=m*n行
发生原因:没有有效的连接条件
如何避免:添加有效的连接条件
分类:
按年代分类:
sql92标准:仅仅支持内连接
sql99标准【推荐】:支持内连接+外连接(左外和右外)+交叉连接
按功能分类:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接
右外连接
全外连接
交叉连接
*/
-- 1.查询员工名和对应的部门名
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 e.last_name,e.job_id,j.job_title
FROM jobs j,employees e
WHERE e.`job_id`=j.`job_id`;
-- 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;
-- 5.查询城市名中第二个字符为o的部门名和城市名
SELECT department_name,city
FROM departments d,locations l
WHERE d.`location_id` = l.`location_id`
AND city LIKE '_o%';
-- 6、可以加分组
-- 查询每个城市的部门个数
SELECT COUNT(*) 个数,city
FROM departments d,locations l
WHERE d.`location_id`=l.`location_id`
GROUP BY city;
-- 7.查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资
SELECT d.department_name, d.manager_id, MIN(salary) 最低工资
FROM departments d, employees e
WHERE d.department_id=e.department_id
AND e.commission_pct is NOT NULL
GROUP BY d.department_name, d.manager_id;
-- 8.可以加排序
-- 查询每个工种的工种名和员工的个数,并且按员工个数降序
SELECT job_title, COUNT(*)
FROM employees e, jobs j
WHERE e.job_id = j.job_id
GROUP BY job_title
ORDER BY COUNT(*) DESC;
-- 内连接:
# 二)、非等值连接
#案例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 e.employee_id,e.last_name,m.employee_id,m.last_name
FROM employees e,employees m
WHERE e.`manager_id`=m.`employee_id`;