10.3.4 分组与合计数据

我们经常需要知道多少行分成一个特定的集合,或一些列的平均值。例如,每个订单的平均金额。MySQL有一组合计函数可实现这类查询。

这些合计函数可以作为一个整体应用于一个表,或者表中的一组数据。最常用的函数如表10-3所示。

10.3.4 分组与合计数据 - 图1

我们来看看一些例子,以前面提到的一个例子为开始。可以如下计算一个订单总金额的平均值:


select avg(amount)

from orders;


输出如下所示:


+——————-+

|avg(amount)|

+——————-+

|54.985002|

+——————-+


要获取更详细的信息,可以使用GROUP BY子句。这使我们可以按分组浏览订单总量的平均值。例如,按照顾客数分组浏览。我们将知道哪些顾客的订单总金额最大:


select customerid,avg(amount)

from orders

group by customerid;


当通过合计函数使用GROUP BY子句的时候,它实际上改变了该函数的行为。该查询并不是给出表中的平均订单总量,而是给出每个顾客(或者,更具体地说,是每个customerid)的平均订单总金额:


+——————+——————-+

|customerid|avg(amount)|

+——————+——————-+

|1|49.990002|

|2|74.980003|

|3|47.485002|

+——————+——————-+


在使用分组和合计函数的时候,需要注意的是:在ANSI SQL中,如果使用了一个合计函数或GROUP BY子句,出现在SELECT子句中的必须是合计函数名称和GROUP BY子句的列名称。同样,如果希望在一个GROUP BY子句中使用一列,该列名称必须在SELECT子句中列出。

MySQL实际上留了一点回旋余地。它支持一种扩展语法(extended syntax),该语法可以在SELECT子句中略去一些实际上并不需要的项目。

除了分组与合计数据,我们实际上还可以使用HAVING子句测试一个合计的结果。它可以直接放在GROUP BY子句后,有些类似于只用于分组与合计的WHERE子句。

对前面的例子进行扩展,如果希望知道哪些顾客的平均订单总金额超过$50,可以使用如下所示的查询:


select customerid,avg(amount)

from orders

group by customerid

having avg(amount)>50;


请注意,HAVING子句应用于这些组。该查询将返回如下所示的输出:


+——————+——————-+

|customerid|avg(amount)|

+——————+——————-+

|2|74.980003|

+——————+——————-+