分组函数(多行处理函数)
即多个输入对应一个输出。前面讲的数据处理函数是单行处理函数。(在公司中常说单,多行处理函数)
分组函数包括五个:
- max:最大值
- min:最小值
- avg:平均值
- sum:求和
- count:计数
例子:
select max(sal),min(sal),avg(sal),sum(sal),count(ename) from emp;
分组函数自动忽略NULL。
例如:count(ename)结果为14,而count(comm)结果为4。(其中comm里面有null)
面试题:count(某个字段)与count(*)的区别。count(某个字段)是统计该字段不为空的总数,count(*)则是统计该表有多少行记录。count(数字)效果跟count(*)一样。
分组函数不能用在where后面
原因:where语句在执行的时候分组函数还没有进行分组
- 分组函数执行之前需要先分组才能在使用
- group by 可以进行分组若是没用group by 则自认为一组
- 执行顺序:from,where,group by ,select,order by
分组查询
group by
注意:
- group by 在where之后执行
- 当sql语句中有group by 则select语句后面只能接参加分组的字段或者分组函数其他的字段不能加
语法:
- 按某个字段分组:group by 字段1
- 按多个字段联合分组:group by 字段1,字段2…
示例
- 示例一:找出每个岗位的平均薪资
- select job,avg(sal) from emp group by job;
示例二:找出每个部门不同岗位的平均薪资
select deptno,avg(sal) from emp group by deptno,job;
过滤 having
两个过滤where与having的区别:
- where:使用where进行过滤是在分组之前进行过滤
- having:使用having进行过滤必须在group by进行分组之后进行过滤
推荐使用where,高效
having示例
示例一:查询每个部门平均薪资,找出平均薪资高于2000的
select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;
执行顺序
from,where,group by ,having,select,order by
组内排序
substring_index函数的使用
语法格式:substring_index('要处理的字符串','分隔符',截取位置)
示例一:select substring_index('abcdaef','a',2);
结果为:abcd示例二:select substring_index(12342,2,2);
结果为:1234
group_concat函数的使用:
GROUP_CONCAT
是 MySQL 中强大的聚合函数,用于将分组后的多行数据合并成单个字符串。
示例:
SELECT department_id,GROUP_CONCAT(DISTINCT expr -- 表达式ORDER BY .....SEPARATOR '; ' -- 自定义分隔符) AS employees
FROM employees
GROUP BY department_id;
参数说明:
组件 | 是否必需 | 说明 | |
---|---|---|---|
DISTINCT | 可选 | 去除重复值 | |
expr | 必需 | 要连接的表达式(列名、计算字段等),可多个:GROUP_CONCAT(col1, col2) | |
ORDER BY | 可选 | 指定连接顺序: • col_name :列名 • expr :表达式 • position :选择列位置(从1开始) • ASC/DESC :排序方向 | |
SEPARATOR | 可选 | 指定连接分隔符(默认逗号, ) 示例:`SEPARATOR ’ | ', SEPARATOR '; '` |
示例
示例一: select job,group_concat(empno) from emp group by job;解释:将每个职位(job)下的所有员工编号(empno)合并成单个字符串,默认用逗号分隔。结果:
+-----------+---------------------+
| job | group_concat(empno) |
+-----------+---------------------+
| ANALYST | 7788,7902 |
| CLERK | 7369,7876,7900,7934 |
| MANAGER | 7566,7698,7782 |
| PRESIDENT | 7839 |
| SALESMAN | 7499,7521,7654,7844 |
+-----------+---------------------+
示例二:找出每个工作岗位的工资排名在前两名的编号代码: select job,substring_index(group_concat(empno),',',2) as empno from emp group by job;结果:
+-----------+-----------+
| job | empno |
+-----------+-----------+
| ANALYST | 7788,7902 |
| CLERK | 7369,7876 |
| MANAGER | 7566,7698 |
| PRESIDENT | 7839 |
| SALESMAN | 7499,7521 |
+-----------+-----------+