MySQL - 11GROUP BY与HAVING的使用

group by的应用场景

我们已经掌握使用select语句结合where查询条件获取需要的数据,但在实际的应用中,还会遇到 下面这类需求,又该如何解决?

  • 公司想知道每个部门有多少名员工
  • 班主任想统计各科第 一名的成绩
  • 某门店想掌握男、女性会员的人数及平均年龄

group by的使用

从字面上理解,group by表示根据某种规则对数据进行分组,它必须配合聚合函数进行使用,对数据进行分组后可以进行count、sum、avg、max和min等运算。

#group by语法
SELECT column_name, aggregate_function(column_name) FROM table_name
GROUP BY column_name

说明:

  1. aggregate_function表示聚合函数。
  2. group by可以对一列或多列进行分组。

having的使用

在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。HAVING 子句可 以对分组后的各组数据进行筛选。

# having语法
SELECT column_name, aggregate_function(column_name) FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value

实战案例

初始化表数据


create table employee(
	id int not null auto_increment primary key,
	name varchar(30),
	sex varchar(1),
	salary int,
	dept varchar(30)
);

insert into employee(name, sex, salary, dept) values('lily0', '1', 5500, 'deptA');
insert into employee(name, sex, salary, dept) values('lily1', '0', 4500, 'deptA');
insert into employee(name, sex, salary, dept) values('lily2', '0', 4200, 'deptB');
insert into employee(name, sex, salary, dept) values('lily3', '1', 7500, 'deptB');
insert into employee(name, sex, salary, dept) values('lily4', '0', 8500, 'deptA');
insert into employee(name, sex, salary, dept) values('lily5', '1', 6800, 'deptB');
insert into employee(name, sex, salary, dept) values('lily6', '1', 12000, 'deptA');
insert into employee(name, sex, salary, dept) values('lily7', '1', 3500, 'deptA');
insert into employee(name, sex, salary, dept) values('lily8', '1', 6000, 'deptC');
insert into employee(name, sex, salary, dept) values('lily9', '1', 8000, 'deptC');
insert into employee(name, sex, salary, dept) values('lily10', '0', 10000, 'deptA');
insert into employee(name, sex, salary, dept) values('lily11', '0', 4000, 'deptA');

group by的使用

mysql> select * from employee;
+----+--------+------+--------+-------+
| id | name   | sex  | salary | dept  |
+----+--------+------+--------+-------+
|  1 | lily0  | 1    |   5500 | deptA |
|  2 | lily1  | 0    |   4500 | deptA |
|  3 | lily2  | 0    |   4200 | deptB |
|  4 | lily3  | 1    |   7500 | deptB |
|  5 | lily4  | 0    |   8500 | deptA |
|  6 | lily5  | 1    |   6800 | deptB |
|  7 | lily6  | 1    |  12000 | deptA |
|  8 | lily7  | 1    |   3500 | deptA |
|  9 | lily8  | 1    |   6000 | deptC |
| 10 | lily9  | 1    |   8000 | deptC |
| 11 | lily10 | 0    |  10000 | deptA |
| 12 | lily11 | 0    |   4000 | deptA |
+----+--------+------+--------+-------+
12 rows in set (0.00 sec)

mysql> select sex, count(*) from employee group by sex;
+------+----------+
| sex  | count(*) |
+------+----------+
| 1    |        7 |
| 0    |        5 |
+------+----------+
2 rows in set (0.00 sec)

mysql> select dept, count(*) from employee group by dept;
+-------+----------+
| dept  | count(*) |
+-------+----------+
| deptA |        7 |
| deptB |        3 |
| deptC |        2 |
+-------+----------+
3 rows in set (0.01 sec)

mysql> 
mysql> select dept, sum(salary) from employee group by dept;
+-------+-------------+
| dept  | sum(salary) |
+-------+-------------+
| deptA |       48000 |
| deptB |       18500 |
| deptC |       14000 |
+-------+-------------+
3 rows in set (0.01 sec)

mysql> select dept, max(salary) from employee group by dept;
+-------+-------------+
| dept  | max(salary) |
+-------+-------------+
| deptA |       12000 |
| deptB |        7500 |
| deptC |        8000 |
+-------+-------------+
3 rows in set (0.00 sec)

mysql> select dept, min(salary) from employee group by dept;
+-------+-------------+
| dept  | min(salary) |
+-------+-------------+
| deptA |        3500 |
| deptB |        4200 |
| deptC |        6000 |
+-------+-------------+
3 rows in set (0.00 sec)

having的使用

mysql> select dept, count(*) from employee group by dept having count(*) < 3;
+-------+----------+
| dept  | count(*) |
+-------+----------+
| deptC |        2 |
+-------+----------+
1 row in set (0.00 sec)

mysql> select dept, max(salary) from employee group by dept having max(salary) > 10000;
+-------+-------------+
| dept  | max(salary) |
+-------+-------------+
| deptA |       12000 |
+-------+-------------+
1 row in set (0.00 sec)

你可能感兴趣的:(MySQL教程)