## MySQL分组 * group by > group by语法可以根据给定字段对查询结果进行分组统计,相同属性的数据为一个组。通常,在每组中通过聚合函数来可以计算组中最大,最小等。 > 如果group by带有having,则只有满足having后面的条件的组才能输出。 注意: having 必须在group by之后。 * 与分组相关的聚合函数 count() 返回某个字段的值的行数 max() 求最大某字段最大的值 min() 求某字段最小值 avg() 返回某字段平均值 sum() 求某字段总数 group_concat() 将分组的结果拼接成字符串 * group by分组SQL语法 select 字段 from 表名 where where条件 group by 分组条件 having having条件 order by 字段 asc/desc limit offset, row 注意: 1. GROUP BY必须出现在WHERE 之后,ORDER BY 之前。 2. 除聚集计算语句外,SELECT语句中的每个列都必须在GROUP BY中给出 //错误,由于name字段没有写到group by之后 select count(id),name,sex from user group by sex; //正确写法 select count(id),name,sex from user group by sex,name; 备注: group by 用于根据字段进行分组 having 指定分组的搜索条件,对分组的结果做进一步的处理 limit 显示查询出来的数据条数 ## 例子 1. 某个员工信息表(staff)结构和数据如下: id name dept salary edlevel hiredate 1 张三 开发部 2000 3 2009-10-11 2 李四 开发部 2500 3 2009-10-01 3 王五 设计部 2600 5 2010-10-02 4 王六 设计部 2300 4 2010-10-03 5 马七 设计部 2100 4 2010-10-06 6 赵八 销售部 3000 5 2010-10-05 7 钱九 销售部 3100 7 2010-10-07 8 孙十 销售部 3500 7 2010-10-06 //staff建表语句 create table staff( id int not null primary key auto_increment, name varchar(200) not null, dept varchar(50) not null comment '部门', salary float(15,2) comment '薪水', edlevel tinyint not null comment '等级', hiredate date not null comment '入职时间' )engine=innodb default charset=utf8; insert into staff(name,dept,salary,edlevel,hiredate) values('张三','开发部',2000,3,'2009-10-11'); insert into staff(name,dept,salary,edlevel,hiredate) values('李四','开发部',2500,3,'2009-10-01'); insert into staff(name,dept,salary,edlevel,hiredate) values('王五','设计部',2600,5,'2010-10-02'); insert into staff(name,dept,salary,edlevel,hiredate) values('王六','设计部',2300,4,'2010-10-03'); insert into staff(name,dept,salary,edlevel,hiredate) values('马七','设计部',2100,4,'2010-10-06'); insert into staff(name,dept,salary,edlevel,hiredate) values('赵八','销售部',3000,5,'2010-10-05'); insert into staff(name,dept,salary,edlevel,hiredate) values('钱九','销售部',3100,7,'2010-10-07'); insert into staff(name,dept,salary,edlevel,hiredate) values('孙十','销售部',3500,7,'2010-10-06'); ## 聚合函数的简单使用 1. 求公司总人数 select count(id) from staff; 2. 求公司薪水支出 select sum(salary) from staff; 3. 求公司最高薪水 select max(salary) from staff; 4. 求公司最低薪水 select min(salary) from staff; 5. 求公司平均薪水 select avg(salary) from staff; ## 分组与聚合函数结合使用例子 例如,统计出各个部门的员工人数 select count(*),dept from staff group by dept; * group_concat函数与group by结合使用例子 求: 得到每个部门的员工的名字 select group_concat(name), dept from staff group by dept; 例如,列出每个部门最高薪水的结果,sql语句如下: 查询结果如下: dept MAXIMUM 开发部 2500 设计部 2600 销售部 3500 select max(salary), dept from staff group by dept; 2. 查询每个部门的总薪水数 select sum(salary), dept from staff group by dept; 查询结果如下: dept total 开发部 4500 设计部 7000 销售部 9600 3. 将where字句与group by 子句一起使用 > 注意: where必须在group by 前面 例子: 查询公司2017年之后入职的各个部门每个级别里的最高薪水 select dept, edlevel, max( salary ) from staff where hiredate > '2017-01-01' grroup by dept; 查询结果如下: DEPT EDLEVEL MAXIMUM 设计部 4 2300 设计部 5 2600 销售部 5 3000 销售部 7 3500 4. 在GROUP BY子句之后使用HAVING子句 > having 可以对分组的结果做进一步处理。 > 可应用限定条件进行分组,以便系统仅对满足条件的组返回结果。为此,在GROUP BY子句后面包含一个HAVING子句。HAVING子句可包含一个或多个用AND和OR连接的谓词。 例如:寻找雇员数超过2个的部门的最高和最低薪水: SELECT DEPT, MAX( salary ) AS MAXIMUM, MIN( salary ) AS MINIMUM FROM staff GROUP BY DEPT HAVING COUNT( * ) >2; 查询结果如下: DEPT MAXIMUM MINIMUM 设计部 2600 2100 销售部 3500 3000 例如:寻找雇员平均工资大于3000的部门的最高和最低薪水: select dept, salary, max(salary),min(salary) from staff group by dept having avg(salary) >2000; 用户想要知道: 最高和最低薪水 条件: 所有组中,找出雇员评价工资大于3000的那些组 所有组: 先分组。 使用having对所有组做进一步处理 查询结果如下: DEPT MAXIMUM MINIMUM 销售部 3500 3000