聚集函数是以值得一个集合(集或多重集)为输入、返回单个值得函数。
SQL提供了五个固有的聚集函数
找出Computer Science 系教师的平均工资。
select avg(salary)
from instructor
where dept_name = 'Comp. Sci.';
将查询1中的查询属性赋予一个有意义的名字
select avg(salary) as avg_salary
from instructor
where dept_name = 'Comp. Sci.';
注意: 在计算平均数时,保留重复元组很重要。
找出在2010年春季学期讲授一门课程的教师总数:
select count(distinct ID)
from teaches
where semester = 'Spring' and year = 2010;
有些情况下,计算聚集函数需要先删除重复元组。可以使用distinct。
找出course关系中的元组数:
select count(*)
from course;
SQL中不允许使用count(*)的时候使用distinct。
使用max和min时,可以使用distinct
使用 group by 将聚集函数作用于一组元组集上。
group by 子句中给出的一个或多个属性是用来构造数组的。在group by 子句中的所有属性上取值相同的元组被分在一个组中。
找出每个系的平均工资
select dept_name, avg(salary) as avg_salary
from instructor
group by dept_name;
找出所有教师的平均工资
select avg(salary)
from instructor;
每个系在2010年春季学期讲授一门课程的教师人数
select dept_name, count(distinct ID) as instr_count
from instructor natural join teaches
where semester = 'Spring' and year = 2010
group by dept_name;
出现在select语句中但没有被聚集的属性,只能是那些出现在group by 子句中那些的属性。换句话说,任何没有出现在group by 中的属性,如果出现在select子句中,它只能出现在聚集函数内部,否则这样的查询就是错误的。
/* 错误的查询*/
select dept_name, ID, avg(salary)
from instructor
group by dept_name;
分析:ID出现在select子句中,且不是聚集函数的参数,却没出现在group by,查询错误。换个思路,一个分组有多个教师,每个教师有不同的ID,每个分组只输出一个元组,那么就无法确定输出哪一个ID。
having子句是对分组的限定。
找出系平均工资超过42000美元的那些系中的教师的平均工资。
select dept_name, avg(salary) as avg_salary
from instructor
group by dept_name
having avg(salary) > 42000;
??? having子句使用 having avg_salary 会有什么不同?
任何出现在having子句中,但没有被聚集的属性必须出现在group by 子句中,否则查询就被当成错误的。
包含聚集、group by或having子句的查询的含义可通过下述操作序列来定义:
1. 最先根据 from 子句计算出一个关系;
2. 如果出现 where 子句, where 子句 中的谓词将应用到 from子句 的结果关系上;
3. 如果出现了group by 子句, 满足 where 谓词的元组通过group by 子句形成分组。 如果没有 group by 子句,满足where谓词的整个元组集被当做一个分组。
4. 如果出现了 having子句,它将应用到每个分组上;不满足having子句谓词的分组将被抛弃。
5. select 子句 利用剩下的分组产生出查询结果中的元组,即在每个分组上应用聚集函数来得到单个结果元组。
“对于在2009年将受的每个课程段,如果该课程段至少2名学生选课,找出选修该课程段的所有学生的总学分(tot_cred)的平均值”。
student(ID, name, dept_name, tot_cred)
takes(ID, course_id, sec_id, semester, year, grade)
select course_id, sec_id, semester,year,avg(tot_cred)
from takes natural join student
where year = 2009
group by course_id,semester,year,sec_id
having count(ID) >= 2;
聚集函数处理空值规则如下:
1. 除了count(*) 外的所有聚集函数都忽略输入集合中的空值。
空值被忽略有可能造成参加函数运算的输入值集合为空。
SQL:1999 中 引入了布尔数据类型,可以取true, false, unknown 三个值。有两个聚集函数some 和 every。