mysql分组查询

一、分组函数

功能:用作统计使用,又称为聚合函数或统计函数或组函数
分类:sum 求和,avg 平均值,max最大值,min最小值,count计算个数

1.简单使用

SELECT SUM(salary) FROM employees;
SELECT AVG(salary) FROM employees;
SELECT MAX(salary) FROM employees;
SELECT MIN(salary) FROM employees;

统计个数:SELECT COUNT(salary) FROM employees;

2.参数支持哪些类型

统计非空值的个数:
SELECT COUNT(salary) FROM employees;  

特点
1.sum,avg 一般用于处理数值类型
max,min,count 可以处理任何类型
2.是否忽略null值(以上分组函数都忽略了null值)
null + 任何值 == null
sum,avg,max,min ,count 都忽略了null值
3.和distinct搭配

select sum(distinct salary),sum(salary) from emloyees;

4.和分组函数一同查询的字段要求是group by后的字段

3.count函数详细介绍

select count(*) from employees;
select count(1) from
employees;

[(1)括号里面的1其实可以是任何常量值,相当于在表上加了一列]
效率:
myisam存储引擎下,count(*)效率高
innodb存储引擎下,count(*)count(1)的效率差不多,比count(字段)要高一些,因为count字段要先判断是否为空
总结:一般用作count(*)统计行数

二、分组查询

1.语法

select 分组函数,列(要求出现在group by 的后面)
from 表
[where 筛选条件]
grop by 分组的列表
[order by 子句]

注意
查询表必须特殊,要求是分组函数和group by后出现的字段

案例1:

查询每个工种的最高工资
select max(salary),job_id
from employees
grop by job_id;

案例2:

查询每个位置上的部门个数
select count(*),location_id
from departments
group by location_id;

2.添加筛选条件(分组前的筛选)

1.查询邮箱中包含a字符的,每个部门的平均工资
select avg(salary),department_id
from employees
where email like '%a%'
group by department_id

2.查询有奖金的每个领导手下员工的最高工资
select max(salary),manage_id
from employees 
where commission_pct 
is not null 
group by manage_id;

3.添加复杂的筛选条件(分组后的筛选)

1.查询哪个部门的员工个数>2
思路:
①.查询每个部门的员工个数
②.根据①的结果进行筛选,查询哪个部门的员工个数>2

select count(*),department_id from 
employees  
group by department_id
having count(*)>2;
因为是要判断 筛选后的结果,所以在 group by 后面追加 语句

2.查询每个工种有奖金的员工的最高工资>12000的工资编号和最高工资
思路:
①.查询每个工种有奖金的员工的最高工资(筛选字段在原始表中由,就可以在from后面使用where关键字)

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

3.查询领导编号>102的每个领导手下的最低工资>5000的领导编号是哪个,以及其最低工资
思路:
①.查询每个领导手下的员工的最低工资

select min(salary),manage_id
from employees
group by manage_id

②.添加筛选条件:编号>102

select min(salary),manage_id
from employees
where manage_id >102
group by manage_id

③.添加筛选条件,最低工资>5000

select min(salary),manage_id
from employees
where manage_id >102
group by manage_id
having min(salary)>5000;

4.按表达式或函数分组

案例:按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5的有哪些
思路:
①.查询每个长度的员工个数

select count(*),length(last_name) len_name
from employees
group by length(last_name);

②.添加筛选条件

select count(*) ,length(last_name) len_name
from employees
group by length(last_name)
having count(*)>5;

5.按多个字段分组

案例:查询每个部门每个工种的员工平均工资,并且按平均工资高低显示

select avg(salary),
department_id,job_id
from employees
group by department_id,job_id
order by avg(salary) desc;

补充说明:(group by后面的顺序是可以颠倒的)

6.特点总结:

1.分组查询中的筛选条件分为两类

数据源 位置 关键字
分组前筛选 原始表 group by 子句的前面 where
分组后筛选 分组后的结果集 group by子句的后面 having

2.分组函数做条件肯定是放在having子句中
3.能用分组前筛选的,就有限考虑使用分组前筛选
4.group by子句支持单个字段分组,多个字段分组(多个字段之间用逗号隔开没有顺序要求),表达式或者函数用的少
5.也可以添加排序(排序放在整个分组查询的最后)
练习1:查询员工最高工资和最低工资的差距

select max(salary)-min(salary) diference
from employees;

练习2:查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计算在内

select min(salary),manage_id
from employees
where manage_id is not null
group by manage_id
having min(salary)>=6000

练习3:查询所有部门的编号,员工数量和工资平均值,并按平均工资降序

select avg(salary) a,department_id,count(*)
from employess
group by department_id
order by a desc;

练习4:选择各个具有job_id的员工人数(题目意思就是按照job_id进行分组)

select count(*) 个数,job_id
from employees
group by job_id;
上一篇:Mysql基础语法


下一篇:MySQL数据库学习 --- 第5天