分组:GROUP BY

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ycd500756/article/details/84191459

1.背景

sql中分组并不陌生,使用起来也不难,见名知意就是将字段具有形同的记录值分为一组。最近的工作中的业务也是经常需要分组分组,所以写点东西记录一下分组常用场景。

2.数据准备

1.运行环境为mysql,版本为5.7.22
2.简单建立一个员工表(tb_emp),表结构和表的字段值如下:

CREATE TABLE `tb_emp` (
  `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT COMMENT '员工id',
  `name` varchar(20) NOT NULL COMMENT '员工姓名',
  `job_id` smallint(5) DEFAULT NULL COMMENT '工种id',
  `dept_id` smallint(5) unsigned DEFAULT NULL COMMENT '部门id',
  PRIMARY KEY (`id`),
  KEY `idx_tbEmp_deptId` (`dept_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;
mysql> SELECT * FROM tb_emp;
+----+--------+--------+---------+
| id | name   | job_id | dept_id |
+----+--------+--------+---------+
|  1 | Mark   |      1 |       1 |
|  2 | Sammi  |      1 |       2 |
|  3 | Abel   |      1 |       2 |
|  4 | Dannel |      2 |       2 |
|  7 | Eason  |      1 |       3 |
|  8 | Sa     |      2 |       3 |
| 10 | Gigi   |      2 |       3 |
+----+--------+--------+---------+
7 rows in set

3.语法结构

SELECT 分组函数,查询列表(要求出现group by的后面)
FROM 原始表
WHERE 分组前的筛选条件
GROUP BY 分组的列表
HAVING 分组后的筛选条件
ORDER BY
LIMIT 

3.单个字段分组

需求1: 查找员工表中各个部门的员工个数

mysql> SELECT COUNT(1) coun,dept_id  FROM tb_emp GROUP BY dept_id; 
+------+---------+
| coun | dept_id |
+------+---------+
|    1 |       1 |
|    3 |       2 |
|    3 |       3 |
+------+---------+
3 rows in set

需求2(加上筛选条件):查找员工表中 部门的员工id大于1 而且 部门的员工个数大于2的部门

mysql> SELECT COUNT(1) coun,dept_id  
       FROM tb_emp 
       WHERE id>1 
       GROUP BY dept_id 
       HAVING coun > 2; 
+------+---------+
| coun | dept_id |
+------+---------+
|    3 |       2 |
|    3 |       3 |
+------+---------+
2 rows in set

分析:部门的员工id大于1,过滤字段id在原始表(tb_emp)就可以找到,该筛选可以在分组前就进行筛选,
所以筛选语句写在where中。部门的员工个数大于2,该筛选的数据源是基于分组后才能进行过滤,那么该条件的筛选语句需要写在having中。

4.基于多个字段进行分组

需求:查找员工表中各个部门各个工种的员工个数。
1.先来看看 根据部门分组 后结果 和 根据工种分组的结果。

mysql> SELECT COUNT(1) coun,dept_id  FROM tb_emp  GROUP BY dept_id ; 
+------+---------+
| coun | dept_id |
+------+---------+
|    1 |       1 |
|    3 |       2 |
|    3 |       3 |
+------+---------+
3 rows in set
mysql> SELECT COUNT(1) coun,job_id  FROM tb_emp  GROUP BY job_id ; 
+------+--------+
| coun | job_id |
+------+--------+
|    4 |      1 |
|    3 |      2 |
+------+--------+
2 rows in set

2.根据部门和工种进行分组, 即相同的部门中相同的工种分为一组。

mysql> SELECT COUNT(1) coun,job_id ,dept_id FROM tb_emp  GROUP BY job_id ,dept_id; 
+------+--------+---------+
| coun | job_id | dept_id |
+------+--------+---------+
|    1 |      1 |       1 |
|    2 |      1 |       2 |
|    1 |      1 |       3 |
|    1 |      2 |       2 |
|    2 |      2 |       3 |
+------+--------+---------+
5 rows in set

5.根据表达式或者函数进行分组

这种使用场景较少
需求:根据员工的名称的长度进行分组,并且计算各组的员工个数。

mysql> SELECT COUNT(1) coun,LENGTH(name) name_len  FROM tb_emp  GROUP BY name_len; 
+------+----------+
| coun | name_len |
+------+----------+
|    1 |        2 |
|    3 |        4 |
|    2 |        5 |
|    1 |        6 |
+------+----------+
4 rows in set

6.总结

1.分组中是筛选条件可以分为两种:

  • 分组前筛选:数据源是原始表(即在mysql中可以看到的表),使用where关键字,sql位置在group by 前面;
  • 分组后筛选:数据源是基于分组后的结果集,使用having关键字,sql位置在group by后面。

2.多个字段分组用逗号分开即可;
3.分组操作后可以添加排序操作。


last edit date: 2018-11-17
location:广州-海珠区-西畔里

猜你喜欢

转载自blog.csdn.net/ycd500756/article/details/84191459