语法:
select 分组函数,字段名
from 表名
【where 筛选前条件】
group by 字段名
【having 分组后筛选】;
注意:
1. group by 后面的字段名必须跟select后的字段名保持一致,可以少于group by中的字段,但不能包含group by中没有的字段
2. 分组需要带上分组函数,分组函数有
- SUM() 求和
- AVG() 平均值
- MIN() 最小值
- MAX() 最大值
- COUNT() 个数
3. 除了count(*)之外,其它分组函数,包括count(column_name),都会忽略分组的列的值为NULL的行
分组函数功能:
用作统计使用,又称为聚合函数、统计函数、组函数
也就是说,我们给他传一组值,最终经过统计和处理,那么我们拿到的是一个值 。
分组函数的特点:
1. sum、avg一般用于处理数值型,max、min、count可以处理任何类型
2. 是否忽略null值, 以上这些分组函数都忽略null值
3. 可以和distinct搭配实现去重的运算
4. count函数的单独介绍,一般使用count(*)用作统计行数
5. 和分组函数一同查询的字段要求是group by后的字段
案例1:查询每个工种的最高工资
SELECT MAX(salary),job_id
FROM employees
GROUP BY job_id;
其中 MAX(salary) 指的是最高工资,这是一个聚合函数,放在 select 语句的后面, job_id 放在聚合函数的后面,证明分组时要按照 job_id 进行分组。
那么 group by 还支持哪些东西呢?
1. 添加分组前的筛选条件进行分组查询
2. 添加分组后的复杂的筛选条件进行分组查询
3. 按表达式或函数分组
4. 按多个字段进行分组
5. 用别名替代可以分组
6. 添加排序进行分组
案例2:查询邮箱中包含字符e的,每个部门的平均工资。 (添加分组前筛选)
从题目中我们得知这里有筛选条件,筛选条件是邮箱中包含字符e,因此得知这是一个分组前的筛选,于是加上聚合函数avg()
SELECT AVG(salary),department_id
FROM employees
WHERE email LIKE '%a%'
GROUP BY department_id;
案例3:查询每个工种有奖金的员工的最高工资>13000的工种编号和最高工资(添加分组后筛选)
查看原始表是分别不出来的,只有通过分组查询后的一个结果集才能查询出来,以前的那种方法行不通的了,现在就添加了一个having子句。
SELECT MAX(salary),job_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX(salary)>13000;
案例4:查询每个部门每个工种的员工的平均工资,并且按平均工资的高低显示(添加排序)
SELECT AVG(salary) 平均工资,department_id,job_id
FROM employees WHERE department_id IS NOT NULL
GROUP BY department_id,job_id
HAVING AVG(salary)>10000 ORDER BY AVG(salary) DESC;
案例5:查询所有部门的编号,员工数量和平均工资,并按照平均工资降序 (添加别名)
SELECT department_id AS '部门编号',COUNT(*) AS '员工数量',ROUND(AVG(salary),2) AS '平均工资'
FROM employees
GROUP BY 部门编号
ORDER BY 平均工资 DESC;
总结(特点):
分组查询中的筛选条件分为两类 数据源不一样 位置 关键字 1)分组前筛选 原始表 group by 子句的前面 where 2)分组后筛选 分组后的结果集 GROUP BY 子句的后面 having ① 分组函数做条件肯定是放在having子句中 ② 能用分组前做筛选的,就优先考虑使用分组前做筛选(考虑到性能的问题) |