MySQL数据库——分组函数和分组查询
#分组函数 /* 功能:用作统计使用,又称为聚合函数或统计函数或组函数 传入一组值,最后拿到一个值 分类: sum 求和 avg 平均值 max min count 计算个数 */ #1.简单使用 工资和 SELECT SUM(salary) FROM employees; SELECT AVG(salary) FROM employees; SELECT COUNT(salary) FROM employees; SELECT SUM(salary) 和, AVG(salary) 平均, MAX(salary) 最高, MIN(salary) 最低,COUNT(salary) 个数 FROM employees; 2.参数类型支持 SUM和AVG:数值型 MAX/MIN/COUNT:数值型、字符型、日期型、任何类型 COUNT:数值型、字符型、日期型、可以为NULL 3.是否忽略NULL SUM/AVG:因为NULL+任何值都为NULL,所以NULL不参与运算 MAX/MIN:如果不忽略要么最小值为NULL,要么最大值为NULL,所以一定忽略 COUNT:忽略NULL值 所以都忽略NULL值 4.可以和DISTINCT搭配 SELECT SUM(DISTINCT salary),SUM(salary) FROM employees; 其他也一样,COUNT也是 5.count函数的详细介绍 SELECT COUNT(salary) FROM employees; SELECT COUNT(*) FROM employees;#统计行数 只要任何字段有一个不为null的都会统计,所以是行数 SELECT COUNT(1) FROM employees;#107 统计1的个数,有多少行就有多少个1 也可以统计2或者其他,也就是在COUNT中加常量值来统计行数 效率: MYISAM存储引擎下,COUNT(*)效率高 INNODB存储引擎下,COUNT(*)和COUNT(1)效率差不多,但是比里头加字段效率高,因为有筛选在里头 一般使用COUNT(*)用作统计函数 6.和分组函数一同查询的字段有限制 SELECT AVG(salary), employee_id FROM employees; AVG完了就一个值,employee_id是一个表 #因此,和分组函数一同查询的字段要求是groud by 的字段 测试: 查询员工表中的最大入职时间和最小入职时间差的天数 SELECT DATEDIFF(MAX(hiredate), MIN(hiredate)) defference FROM employees; 查询自己活了多少天 SELECT DATEDIFF('2021-2-17','1996-11-3'); 查询部门编号为90的员工个数 SELECT COUNT(*) FROM employees WHERE department_id = 90;
#进阶5:分组查询 #引入:查询每个部门的平均工资 SELECT AVG(salary) FROM employees; #使用group by子句,搭配分组函数一起使用 /* select 分组函数,列(要求出现在group by后面) from 表 where 条件 group by 分组的列表 order by 子句 注意:查询列表必须特殊,要求是分组函数和group by后出现的字段 特点: 1.分组查询中的筛选条件分为分类:数据源不一样 分组前筛选: 数据源是原数据 位置在group by子句前面 where关键字 分组后筛选: 数据源是分组后的结果集 放在group by子句后面 having关键字 分组函数做条件,肯定是放在having 子句中,属于分组后筛选 能用分组前筛选优先考虑使用! 2.group by子句支持单个字段分组,也支持多个字段分组,之间用逗号隔开没有顺序要求,也支持表达式函数,但是较少 3.也可以添加排序,排序放在整个分组查询最后! */ #案例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 BY 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; #②根据①的结果进行筛选 SELECT COUNT(*),department_id FROM employees GROUP BY department_id HAVING COUNT(*) > 2; #案例6:查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资 #①查询每个工种有奖金的员工的最高工资 SELECT MAX(salary),job_id FROM employees WHERE commission_pct IS NOT NULL GROUP BY job_id; #②根据①的结果,查询>12000的工种编号和最高工资 SELECT MAX(salary),job_id FROM employees WHERE commission_pct IS NOT NULL GROUP BY job_id HAVING MAX(salary) > 12000; #案例7:查询领导编号大于102的每个领导手下的最低工资大于5000的领导编号是哪个,以及最低工资 #①查询领导编号大于102的每个领导手下的员工的最低工资 SELECT MIN(salary),manager_id FROM employees WHERE manager_id > 102 GROUP BY manager_id; #②根据①查询大于5000的领导编号和最低工资 SELECT MIN(salary),manager_id FROM employees WHERE manager_id > 102 GROUP BY manager_id HAVING MIN(salary) > 5000; #按表达式分组、函数分组 #案例8:按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数大于5的 #①查询每个长度的员工个数 SELECT COUNT(*),LENGTH(last_name) FROM employees GROUP BY LENGTH(last_name); #②添加筛选条件:筛选员工个数大于5的:分组后结果集 SELECT COUNT(*),LENGTH(last_name) FROM employees GROUP BY LENGTH(last_name)#支持别名 HAVING COUNT(*) > 5;#支持别名 #按多个字段分组 #案例:查询每个部门每个工种员工的平均工资 #将多个字段都一样的进行合并,否则不合并 SELECT AVG(salary),department_id,job_id FROM employees GROUP BY department_id,job_id; #添加排序 #案例:查询每个部门每个工种员工的平均工资并且按工资降序排序 SELECT AVG(salary),department_id,job_id FROM employees WHERE department_id IS NOT NULL GROUP BY department_id,job_id ORDER BY AVG(salary) DESC; #测试 #查询每个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的不计算在内 SELECT MIN(salary),manager_id FROM employees WHERE manager_id IS NOT NULL GROUP BY manager_id HAVING MIN(salary) >= 6000; #查询所有部门的编号,员工数量和工资平均值,并按平均值工资降序排列 SELECT department_id,COUNT(*),AVG(salary) FROM employees GROUP BY department_id ORDER BY AVG(salary) DESC; #选择具有各个job_id的员工人数 SELECT COUNT(*),job_id FROM employees GROUP BY job_id;