SQL笔记(六) 聚集函数

聚集函数

  • 聚集函数
    • 固有的聚集函数
    • 基本聚集
          • 查询1. 平均数
          • 查询2. as 重命名平均数
          • 查询3. distinct 使用的情况。
          • 查询4. count(*)
    • 分组聚集
          • 查询5.
          • 查询6.整个关系作为一个分组
          • 查询7.
      • 重要结论
          • 查询8. 一个错误的查询
    • having子句
          • 查询9. having子句
      • 包含聚集、group by或having子句的查询
          • 查询10.同时使用having和where子句
    • 对空值和布尔值的聚集

聚集函数是以值得一个集合(集或多重集)为输入、返回单个值得函数。

固有的聚集函数

SQL提供了五个固有的聚集函数

  • 平均值 :avg
  • 最小值: min
  • 最大值:max
  • 总和: sum
  • 计数: count

基本聚集

查询1. 平均数

找出Computer Science 系教师的平均工资。

select avg(salary)
from instructor
where dept_name = 'Comp. Sci.';
查询2. as 重命名平均数

将查询1中的查询属性赋予一个有意义的名字

select avg(salary) as avg_salary
from instructor
where dept_name = 'Comp. Sci.';

注意: 在计算平均数时,保留重复元组很重要。

查询3. distinct 使用的情况。

找出在2010年春季学期讲授一门课程的教师总数:

select count(distinct ID)
from teaches
where semester = 'Spring' and year = 2010;

有些情况下,计算聚集函数需要先删除重复元组。可以使用distinct。

查询4. count(*)

找出course关系中的元组数:

select  count(*)
from course;

SQL中不允许使用count(*)的时候使用distinct。
使用max和min时,可以使用distinct

分组聚集

使用 group by 将聚集函数作用于一组元组集上。
group by 子句中给出的一个或多个属性是用来构造数组的。在group by 子句中的所有属性上取值相同的元组被分在一个组中。

查询5.

找出每个系的平均工资

select dept_name, avg(salary) as avg_salary
from instructor
group by dept_name;
查询6.整个关系作为一个分组

找出所有教师的平均工资

select avg(salary)
from instructor;
查询7.

每个系在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子句中,它只能出现在聚集函数内部,否则这样的查询就是错误的。

查询8. 一个错误的查询
/*  错误的查询*/
select dept_name, ID, avg(salary)
from instructor
group by dept_name;

分析:ID出现在select子句中,且不是聚集函数的参数,却没出现在group by,查询错误。换个思路,一个分组有多个教师,每个教师有不同的ID,每个分组只输出一个元组,那么就无法确定输出哪一个ID。

having子句

having子句是对分组的限定。

查询9. 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子句的查询

包含聚集、group by或having子句的查询的含义可通过下述操作序列来定义:
1. 最先根据 from 子句计算出一个关系;
2. 如果出现 where 子句where 子句 中的谓词将应用到 from子句 的结果关系上;
3. 如果出现了group by 子句满足 where 谓词的元组通过group by 子句形成分组。 如果没有 group by 子句,满足where谓词的整个元组集被当做一个分组。
4. 如果出现了 having子句,它将应用到每个分组上;不满足having子句谓词的分组将被抛弃。
5. select 子句 利用剩下的分组产生出查询结果中的元组,即在每个分组上应用聚集函数来得到单个结果元组。

查询10.同时使用having和where子句

“对于在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(*) 外的所有聚集函数都忽略输入集合中的空值。

空值被忽略有可能造成参加函数运算的输入值集合为空。


  1. 规定空集的count运算值为0 ;其他所有聚集运算在输入为空集的情况下返回一个空值。

SQL:1999 中 引入了布尔数据类型,可以取true, false, unknown 三个值。有两个聚集函数some 和 every。

你可能感兴趣的:(初级SQL)