0 0 0

单表数据记录查询—聚合函数和分组记录查询

ZAESKY
2020-1-27 3411

在数据库中,通常需要进行一些数据汇总操作。比如,要统计汇总商品种类或者统计整个公司的员工数等,此时就用到了聚合函数MySQL所支持的聚合函数一共有以下5种。

COUNT()函数:计算表中记录的条数。

SUM()函数:计算字段值的总和。

AVG()函数:计算字段值的平均值。

MAX()函数:查询表中字段值的最大值。

MIN()函数:查询表中字段值的最小值。

实际应用中,聚合函数通常与分组查询一起使用。分组查询就是按照某个字段对数据记录进行分组,比如前面用到的goods表,可以按照商品类别对记录进行分组,然后使用聚合函数统计每个类别下的商品数量。

使用聚合函数查询的基本语法形式如下:

SELECT function(*|col_num) FROM table_name WHERE CONDITION;

本节依然以db_shop数据库中的goods表为例进行操作,在操作之前,先执行以下语句,向数据表中追加5条记录。

INSERT INTO goods(id,type,name,price,num,add_time)
VALUES(6,'书籍','论语',109,50,'2018-01-03 13:40:40'),
(7,'水果','西瓜',1.5,null,'2018-02-05 13:40:40'),
(8,'水果','苹果',3,100,'2018-03-05 13:40:40'),
(9,'服饰','牛仔裤',120,10,'2018-05-04 13:40:40'),
(10,'书籍','红楼梦',50.5,15,'2018-05-06 13:40:40');


一、使用聚合函数查询

1.1 COUNT()函数

COUNT()函数用于统计数据记录条数,用于返回表中记录的条数,或者符合特定条件的记录条数

COUNT(*)计算表中总的记录数,不管表字段中是否包含NULL值。 

COUNT(col_name)计算表中指定字段的记录数,在具体统计时将忽略NULL值。

实例1:执行SQL语句,查询goods表中总的记录条数,执行结果如下。

mysql> SELECT COUNT(*) AS goods_num FROM goods;
+-------------------------+
| goods_num  |
+-------------------------+
|        10    |
+-------------------------+
1 row in set (0.06 sec)

上述语句中使用AS关键字为字段取别名为goods_num,使得查询结果简单明了,AS关键字可省略。使用AS关键字不仅可以为字段取别名,还可为表取别名,其使用非常灵活。

实例2:执行SQL语句,查询goods表中有库存(num值不为NULL)的记录条数,执行结果如下

mysql> SELECT COUNT(num) AS goods_num FROM goods;
+----------------+
| goods_num |
+----------------+
|         9       |
+----------------+
1 row in set (0.01 sec)


1.2 SUM()函数

SUM()函数是一个求总和的函数,用于返回指定字段值的总和,或符合特定条件的指定字段值总和具体计算时将忽略NULL值。其使用方法如下:

SUM(col_name)

实例3:执行SQL语句,查询goods表中商品库存的总和,执行结果如下

mysql> SELECT SUM(num) goods_num FROM goods;
+-----------------+
| goods_num  |
+-----------------+
|       575         |
+-----------------+
1 row in set (0.04 sec)


1.3 AVG()函数

AVG()函数通过计算返回的行数和每一行数据的和,得到指定列数据的平均值,在具体计算时将忽略NULL值。AVG()函数与GROUP BY一起使用,可以计算每个分组的平均值。其使用方式如下:

AVG(col_name)

实例4:执行SQL语句,查询goods表中每个商品类别的平均价格,执行结果如下

mysql> SELECT type,AVG(price) FROM goods GROUP BY type;
+------+---------------------+
| type | AVG(price)  |
+------+---------------------+
| 书籍 |  69.966667  |
| 服饰 | 460.000000  |
| 水果 |   2.250000  |
| 糖类 |   5.000000  |
| 饮品 |   2.500000  |
+------+---------------------+
5 rows in set (0.03 sec)


1.4 MAX()函数和MIN()函数

MAX()函数和MIN()函数是用于求最大值和最小值的函数,可返回指定字段中的最大值和最小值或者符合特定条件的指定字段值中的最大值和最小值。

MAX(col_name)该方式可以实现计算指定字段值中的最大值,在具体计算时将忽略NULL值。 

MIN(col_name)该方式可以实现计算指定字段值中的最小值,在具体计算时将忽略NULL值。

实例5:执行SQL语句,查询goods表中商品的最高价格和最低价格,执行结果如下

mysql> SELECT MAX(price) maxpri,MIN(price) minpri FROM goods;
+----------+-----------+
| maxpri  | minpri  |
+----------+-----------+
| 800.00  |   1.50  |
+----------+-----------+
1 row in set (0.04 sec)


二、分组查询

分组查询是将查询结果按照某个或多个字段进行分组,MySQL使用GROUP BY语句对数据进行分组。GROUP BY从字面上理解就是“根据(BY)一定的规则进行分组(GROUP)”。它的工作原理是按照一定的规则将一个数据集合划分成若干个小的区域,然后针对这些区域的数据进行处理,语法形式如下:

SELECT {*|col_list} aggregate_func FROM table_name 
GROUP BY col_namea [HAVING condition];

2.1 简单分组查询

GROUP BY关键字与聚合函数COUNT()一起使用,可以查询每组的数量。

实例6:执行SQL语句,将goods表中的记录按照type字段(商品类别)进行分组,并统计每组的数量,结果如下

mysql> SELECT type,count(*) FROM goods GROUP BY type;
+------+--------------+
| type | count(*)  |
+------+--------------+
| 书籍 |        3  |
| 服饰 |        2  |
| 水果 |        2  |
| 糖类 |        2  |
| 饮品 |        1  |
+------+--------------+
5 rows in set (0.02 sec)

如果需要将每种类型中包含的商品名称显示出来,可以使用group_concat()函数

实例7:执行SQL语句,将goods表中的记录按照type字段进行分组,并显示每组中的商品名称,结果如下

mysql> SELECT type,group_concat(name) FROM goods GROUP BY type;
+------+--------------------------------+
| type | group_concat(name)   |
+------+--------------------------------+
| 书籍 | 西游记,论语,红楼梦   |
| 服饰 | 休闲西服,牛仔裤   |
| 水果 | 西瓜,苹果   |
| 糖类 | 牛奶糖,水果糖   |
| 饮品 | 果汁   |
+------+--------------------------------+
5 rows in set (0.00 sec)


2.2 使用HAVING过滤分组后数据

GROUP BYHAVING一起使用,可以指定显示记录所需满足的条件,只有满足条件的分组才会被显示。

实例8:执行SQL语句,将goods表中的记录按照type字段分组并统计每组的数量,然后只取商品数量大于1的分组,结果如下

mysql> SELECT type,count(*) FROM goods GROUP BY type HAVING COUNT(*)>1;
+------+------------------+
| type | count(*)  |
+------+------------------+
| 书籍 |        3  |
| 服饰 |        2  |
| 水果 |        2  |
| 糖类 |        2  |
+------+------------------+
4 rows in set (0.06 sec)

WHERE子句和HAVING子句都具有按照条件筛选数据的功能,两者的区别主要有以下几点

WHERE子句在进行分组操作之前用来选择记录,而HAVING子句在进行分组操作之后通过过滤来选择分组。 

HAVING子句中的每个字段必须被包含在SELECT关键字后的字段列表中。 

HAVING子句可以包含聚合函数,但WHERE子句不能


2.3 使用多个字段进行分组

使用GROUP BY不止可以按照一个字段进行分组,还可以按多个字段进行分组。分组层次从左到右先按第1个字段进行分组,然后对第1个字段值相同的记录,再根据第2个字段进行分组,依此类推。

实例9:执行SQL语句,将goods表中的记录按照typenum字段进行分组并统计,显示每个分组中商品类别、库存、商品名称和商品数量,执行结果如下

mysql> SELECT type,num,group_concat(name),count(name) FROM goods GROUP BY type,num;
+--------+--------+---------------------------+---------------------------+
| type  | num   | group_concat(name)| count(name)  |
+--------+--------+---------------------------+---------------------------+
| 书籍 |   15      | 红楼梦    |          1   |
| 书籍 |   20      | 西游记    |          1   |
| 书籍 |   50      | 论语    |          1   |
| 服饰 |   10      | 休闲西服,牛仔裤    |          2  |
| 水果 | NULL  | 西瓜    |          1   |
| 水果 |  100    | 苹果    |          1   |
| 糖类 |  100    | 水果糖    |          1   |
| 糖类 |  200    | 牛奶糖    |          1   |
| 饮品 |   70       | 果汁    |          1  |
+--------+--------+---------------------------+---------------------------+
9 rows in set (0.01 sec)


最新回复 (0)

    暂无评论

请先登录后发表评论!

返回
请先登录后发表评论!