【MySQL】聚合查询与分组查询
我们先重建一个test库,在test库里新建一个people表(包含序列号,姓名,工资),再往表该表里新增六条数据:
mysql> drop database if exists test; Query OK, 1 row affected (0.07 sec) mysql> create database test; Query OK, 1 row affected (0.00 sec) mysql> use test; Database changed mysql> create table people( -> id int primary key auto_increment, -> name varchar(20), -> careen varchar(20), -> salary int -> ); Query OK, 0 rows affected (0.05 sec) mysql> insert into people value(null,"张三","老师",3000); Query OK, 1 row affected (0.01 sec) mysql> insert into people value(null,"李四","老师",4000); Query OK, 1 row affected (0.01 sec) mysql> insert into people value(null,"王五","老师",5000); Query OK, 1 row affected (0.01 sec) mysql> insert into people value(null,"赵六","医生",60000); Query OK, 1 row affected (0.00 sec) mysql> insert into people value(null,"小七","医生",70000); Query OK, 1 row affected (0.00 sec) mysql> insert into people value(null,null,null,null); Query OK, 1 row affected (0.00 sec) mysql> select * from people; +----+--------+--------+--------+ | id | name | careen | salary | +----+--------+--------+--------+ | 1 | 张三 | 老师 | 3000 | | 2 | 李四 | 老师 | 4000 | | 3 | 王五 | 老师 | 5000 | | 4 | 赵六 | 医生 | 60000 | | 5 | 小七 | 医生 | 70000 | | 6 | NULL | NULL | NULL | +----+--------+--------+--------+ 6 rows in set (0.00 sec)
接下来我们就针对该表进行聚合查询操作~
♫聚合查询
前面我们所用的基础的查询操作只能对每行进行独立的查询操作,而要是想要查询的结果是该列所有数据的平均值,最大或最小值,则需要使用聚合查询才能做到。聚合查询需要用到聚合函数,因此,要学会聚合查询,首先得先了解下MySQL中的聚合函数。
♪聚合函数
常见的聚合函数有以下几种:
函数 描述 COUNT([DISTINCT] expr) 返回查询到的数据的数量AVG([DISTINCT] expr) 返回查询到的数据的总和,不是数字没有意义SUM([DISTINCT] expr) 返回查询到的数据的平均值,不是数字没有意义MAX([DISTINCT] expr) 返回查询到的数据的最大值,不是数字没有意义MIN([DISTINCT] expr) 返回查询到的数据的最小值,不是数字没有意义知道了聚合函数,接下来就可以使用这些聚合函数进行聚合查询操作了。
♪查询表的行数
查询表的行数需要用到聚合函数count():
语法:select count(*) from 表名;
mysql> select count(*) from people; +----------+ | count(*) | +----------+ | 6 | +----------+ 1 row in set (0.00 sec)
此外count(常量)也能查询表的行数:
语法:select count(常量) from 表名;
mysql> select count(1) from people; +----------+ | count(1) | +----------+ | 6 | +----------+ 1 row in set (0.00 sec)
注:
①.count(1)和count(*)的实现方式略有不同,count(1)是对表中的每一行都执行一次计数操作,而count(*)则是对整个表执行计数操作
②.查询表的行数包括全为NULL的行
♪查询表某一列的行数
单独查询表某一列有几行也是需要用到count():
语法:select count(列名/表达式) from 表名;
mysql> select count(name) from people; +----------------+ | count(name) | +----------------+ | 5 | +----------------+ 1 row in set, 5 warnings (0.00 sec)
注:查询某一列的行数不会包含NULL数据
♪查询表某一列数据的和
要想查询结果是某一列的数据和就需要用到聚合函数sum():
语法:select sum(列名/表达式) from 表名;
mysql> select sum(salary) from people; +-------------+ | sum(salary) | +-------------+ | 142000 | +-------------+ 1 row in set (0.00 sec)
注:只能查询数字列的和,不能求字符串/日期的和
♪查询表某一列数据的平均值
要查询某一列数据的平均值就需要用到聚合函数avg():
语法:select avg(列名/表达式) from 表名;
mysql> select avg(salary) from people; +-------------+ | avg(salary) | +-------------+ | 28400.0000 | +-------------+ 1 row in set (0.00 sec)
注:只能查询数字列的平均值
♪查询表某一列数据的最大值
要查询某一列数据的最大值就需要用到聚合函数max():
语法:select max(列名/表达式) from 表名;
mysql> select max(salary) from people; +-------------+ | max(salary) | +-------------+ | 70000 | +-------------+ 1 row in set (0.00 sec)
注:只能查询数字列的最大值
♪查询表某一列数据的最小值
要查询某一列数据的最小值就需要用到聚合函数min():
语法:select min(列名/表达式) from 表名;
mysql> select min(salary) from people; +-------------+ | min(salary) | +-------------+ | 3000 | +-------------+ 1 row in set (0.00 sec)
注:只能查询数字列的最小值
上面聚合查询的对象是所有人,要想查询的对象为同一职业的人,可以通过group by子句来实现。
♫分组查询
♪group by子句
select中使用 group by 子句可以对指定列进行分组查询。需要满足:使用group by 进行分组查询时,select 指定的字段必须是 “ 分组依据字段 ” ,其他字段若想出现在 select 中则必须包含在聚合函数中。语法:select 列名,聚合函数,... from 表名 group by 列名;
-- 查询每种职业的最高薪资 mysql> select careen,max(salary) from people group by careen; +--------+-------------+ | careen | max(salary) | +--------+-------------+ | NULL | NULL | | 医生 | 70000 | | 老师 | 5000 | +--------+-------------+ 3 rows in set (0.01 sec)
如果是不带聚合函数的分组查询,查询结果为每个分组的第一条记录:
mysql> select * from people group by careen; +----+--------+--------+--------+ | id | name | careen | salary | +----+--------+--------+--------+ | 6 | NULL | NULL | NULL | | 4 | 赵六 | 医生 | 60000 | | 1 | 张三 | 老师 | 3000 | +----+--------+--------+--------+ 3 rows in set (0.01 sec)
分组查询还可以对分组前指定条件或对分组后指定条件:
♪分组前指定条件
对筛选出来的数据进行分组查询:
语法:select 列名,聚合函数,... from 表名 group by 列名 where 指定条件;
-- 取所有工资大于3000的人,对这类人按照对应职业进行分组查询 mysql> select careen,avg(salary) from people where salary>3000 group by careen; +--------+-------------+ | careen | avg(salary) | +--------+-------------+ | 医生 | 65000.0000 | | 老师 | 4500.0000 | +--------+-------------+ 2 rows in set (0.02 sec)
♪分组后指定条件
对分组查询后的数据进行筛选:
语法:select 列名,聚合函数,... from 表名 group by 列名 having 指定条件;
-- -- 按照职业进行分组查询,取查询结果中平均工资大于5000的职业 mysql> select careen,avg(salary) from people group by careen having avg(salary)>5000; +--------+-------------+ | careen | avg(salary) | +--------+-------------+ | 医生 | 65000.0000 | +--------+-------------+ 1 row in set (0.00 sec)