汇总数据
本章介绍什么是SQL的聚集函数以及如何利用它们汇总表的数据。
聚集函数
我们经常需要汇总数据而不用把它们实际检索出来,为此MySQL提供了专门的函数。通过这些函数,MySQL查询可用于检索数据,以便分析和报表生成。
常见类型:
- 确定表中行数(或满足某个条件或包含某个特定值的行数)。
- 获得表中行组的和。
- 找出表列(或所有行或某些特定的行)的最大值、最小值和平均值。
这些都是对表中数据(而不是实际数据本身)汇总。故,返回实际数据是对时间和处理资源的一种浪费。
MySQL给出了5个聚集函数:
函数 | 说明 |
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列之和 |
- 聚集函数(aggregate function) 运行在行组上,计算和返回单个值的函数。
- 标准偏差 MySQL还支持一系列的标准偏差聚集函数。
AVG()函数
AVG()通过对表中行数计数并计算特定列值之和,求得该列的平均值。
返回products表中所有产品的平均价格:
mysql> SELECT AVG(prod_price) AS avg_price
-> FROM products;
+-----------+
| avg_price |
+-----------+
| 16.133571 |
+-----------+
1 row in set (0.02 sec)
此SELECT语句返回值avg_price,它包含products表中所有产品的平均价格。avg_price是一个别名(MySQL必知必会——第十章创建计算字段)。
AVG()也可以用来确定特定列或行的平均值:
mysql> SELECT AVG(prod_price) AS avg_price
-> FROM products
-> WHERE vend_id = 1003;
+-----------+
| avg_price |
+-----------+
| 13.212857 |
+-----------+
1 row in set (0.01 sec)
此SELECT语句包含了WHERE子句,仅过滤出vend_id为1003的产品,所以avg_price仅返回供应商1003的产品的平均值。
- 只用于单个列 AVG()只能确定特定数值列的平均值,且列名必须作为参数。
- NULL值 AVG()函数忽略列值为NULL的行。
COUNT()函数
COUNT()函数进行计数。可用COUNT()确定表中行的数目或符合特定条件的行的数目。
使用COUNT()函数的两种方式:
- 使用COUNT(*)对表中行的数目进行计数,包含NULL值列。
- 使用COUNT(column)对特定列中具有值的行就行计数,忽略NULL值。
返回customers表中客户的总数:
mysql> SELECT COUNT(*) AS num_cust
-> FROM customers;
+----------+
| num_cust |
+----------+
| 5 |
+----------+
1 row in set (0.01 sec)
此语句利用COUNT(*)对所有行计数。
对具有邮件地址的客户计数:
mysql> SELECT COUNT(cust_email) AS num_cust
-> FROM customers;
+----------+
| num_cust |
+----------+
| 3 |
+----------+
1 row in set (0.00 sec)
这条SELECT语句使用COUNT(cust_email)对cust_email列中有值的行进行计数。
- NULL值 如果指定列名,则指定列的值为NULL的行将被忽略,但如果函数用*号,则不忽略。
MAX()函数
MAX()返回指定列中的最大值。MAX()要求指定列名。
返回products表中最贵的物品价格:
mysql> SELECT MAX(prod_price) AS max_price
-> FROM products;
+-----------+
| max_price |
+-----------+
| 55.00 |
+-----------+
1 row in set (0.00 sec)
- 对非数值数据使用MAX() MAX()一般用来找出最大的数值或日期值,但MySQL允许将它用来返回任意列中的最大值,包括返回文本列中的最大值。用于文本数据时,返回最后一行。
- NULL值 MAX()函数忽略列值为NULL的行。
MIN()函数
MIN()返回指定列的最小值。MIN()要求指定列名。
返回products表中最便宜的物品价格:
mysql> SELECT MIN(prod_price) AS min_price
-> FROM products;
+-----------+
| min_price |
+-----------+
| 2.50 |
+-----------+
1 row in set (0.00 sec)
- 对非数值数据使用MAX() MIN()与MAX()类似,MySQL允许将它用来返回任意列中的最小值,包括返回文本列中的最小值。用于文本数据时,返回最前面一行。
- NULL值 MIN()函数忽略列值为NULL的行。
SUM()函数
SUM()返回指定列值的和(总计)。
检索订单号20005所订购物品的总数(所有quantity值之和):
mysql> SELECT SUM(quantity) AS items_ordered
-> FROM orderitems
-> WHERE order_num = 20005;
+---------------+
| items_ordered |
+---------------+
| 19 |
+---------------+
1 row in set (0.00 sec)
SUM()也可以合计计算值,计算总订单金额(item_price*quantity):
mysql> SELECT SUM(item_price*quantity) AS total_price
-> FROM orderitems
-> WHERE order_num = 20005;
+-------------+
| total_price |
+-------------+
| 149.87 |
+-------------+
1 row in set (0.00 sec)
- 在多个列上进行计算 利用标准的算术操作符,所有聚集函数都可用来执行多个列上的计算。
- NULL值 SUM()函数忽略列值为NULL的行。
聚集不同值
以上聚集函数都可以如下使用:
- 对所有行执行计算,指定ALL参数或不给参数(ALL为默认)。
- 只包含不同的值,指定DISTINCT参数。
使用DISTINCT参数检索特定供应商提供的产品的平均价格:
mysql> SELECT AVG(DISTINCT prod_price) AS avg_price
-> FROM products
-> WHERE vend_id = 1003;
+-----------+
| avg_price |
+-----------+
| 15.998000 |
+-----------+
1 row in set (0.00 sec)
使用DISTINCT后,avg_price比第一个例子更高,因为多个物品具有相同的价格,排除它们提升了平均价格。
- ALL为默认 ALL参数不需要指定,因为它是默认行为。
- 注意 DISTINCT不能用于COUNT(*),否则会产生错误。即,DISTINCT必须使用列名,不能用于计算或表达式。
- 将DISTINCT用于MIN()和MAX() 虽然DISTINCT可以用于MIN()和MAX(),但没有价值,最大最小值只有一个。
组合聚集函数
SELECT语句可根据需要包含多个聚集函数:
mysql> SELECT COUNT(*) AS num_items,
MIN(prod_price) AS price_min,
MAX(prod_price) AS price_max,
AVG(prod_price) AS price_avg
-> FROM products;
+-----------+-----------+-----------+-----------+
| num_items | price_min | price_max | price_avg |
+-----------+-----------+-----------+-----------+
| 14 | 2.50 | 55.00 | 16.133571 |
+-----------+-----------+-----------+-----------+
1 row in set (0.00 sec)
这里用单条SELECT语句执行4个聚集计算。
- 取别名 在指定别名以包含某个聚集函数的结果时,不应该使用表中实际的列名。唯一的名字使你的代码更易于理解和使用。