聚集函数(aggregate function)是以值集集合或多重集合)为输入返回单个值的函数。SQL提供了五个标准的固有聚集函数。

  • 平均值:avg
  • 最小值:min
  • 最大值:max
  • 总和:sum
  • 计数:count
    sumavg的输入必须是数字集,但其他运算可以作用在非数字数据类型的集合上,比如字符串
基本聚集

有时在计算聚集函数前必须先去重。如果确实想去除重复项,可在聚集表达式中使用关键字distinct
我们经常使用聚集函数count计算一个关系中元组的数量。在SQL中该函数的写法是count(*)。因此,要找出course关系中的元组数,可写成:

select count(*)
from course;

SQL不允许在用count(*)时使用distinct。在用max和min时使用distinct是合法的,尽管结果并没有差别。我们可以使用关键字all替代distinct来表明要保留重复项,但既然all是缺省的,就没必要这么做了。


分组聚集

有时候我们不仅希望将聚集函数作用在单个元组集上,而且希望将其作用在一组元组集上;在SQL中可使用group by子句实现这个愿望。group by子句中给出的一个或多个属性是用来构造分组的。在分组(group by)子句中的所有属性上取值相同的元组将被分在一个组内。
分组是计算查询结果的第一步。在每个分组上都要进行指定的聚集计算。
当SQL查询使用分组时,一个很重要的事情是确保出现在select语句中但没有被聚集的属性只能出现在group by子句中的那些属性。换句话说,任何没有出现在group by子句中的属性如果出现在select子句中,它只能作为聚集函数的参数,否则这样的查询就是错误的
例如,下述查询是错误的,因为ID没有出现在group by子句中,但它出现在了select子句中,而且没有被聚集:

/*错误查询*/
select dept_name,ID,avg(salary)
from instructor
group by dept_name;

在上述查询中,一个特定分组(通过dept_name定义)中的每位教师都可以有一个不同的ID,既然每个分组只输出一个元组,那就无法确定选哪个ID值作为唯一输出。其结果是,SQL不允许这样的情况出现。
上述查询还展示了在SQL中用“/ /”包含文本的方式来编写注释,同样的注释也可以写为“–错误查询”。


having子句

有时候,对分组限定条件比对元组限定条件更有用。例如,我们也许只对教师平均工资超过4200美元的那些系感兴趣。该条件并不针对单个元组,而是针对group by子句构成的每个分组。为表达这样的查询,我们使用SQL的having子句。SQL在形成分组后才应用having子句中的谓词,因此在having子句中可以使用聚集函数。我们用SQL表达该查询如下:

select dept_name,avg(salary) as avg_salary
from instructor
group by dept_name
having avg(salary)>42000;

与select子句的情况类似,任何出现在having子句中,但没有被聚集的属性必须出现在group by子句中,否则查询就是错误的
包含聚集group byhaving子句的查询的含义可通过下述运算序列来定义:

  • 1.与不带聚集的查询情况类似,首先根据from子句来计算出一个关系。
  • 2.如果出现了where子句,where子句中的谓词将应用到from子句的结果关系上。
  • 3.如果出现了group by子句,满足where谓词的元组通过group by子句被放入分组中。如果没有group by子句,满足where谓词的整个元组集被当成一个分组。
  • 4.如果出现了having子句,它将应用到每个分组上;不满足having子句谓词的分组将被去掉。
  • 5.select子句利用剩下的分组产生查询结果中的元组,即在每个分组上应用聚集函数来得到单个结果元组。

对空值和布尔值的聚集

空值的存在给聚集运算的处理带来了麻烦。例如,假设instructor关系中有些元组在salary上取空值。考虑以下计算所有教师工资总额的查询:

select sum(salary)
from instructor

由于我们假设某些元组在salary上取空值,上述查询待求和的值中就包含了空值。SQL标准并不认为总和本身为null,而是认为sum运算符应忽略其输入中的null值
总而言之,聚集函数根据以下原则处理空值:

  • 除了count(*)之外的所有聚集函数都忽略其输入集合中的空值
  • 由于空值被忽略,聚集函数的输入值集合有可能为空集
  • 规定空集的count运算为0,并且当作用在空集上时,其他所有的聚集运算返回一个空值
  • 在一些更复杂的SQL结构中空值的影响会更难以琢磨。
    在SQL:1999中引入了布尔(boolean)数据类型,它可以取truefalseunknown三种值。聚集函数someevery应用于布尔值的集合,并分别计算这些值的析取(or)与合取(and)