第9讲:结果计算与聚集计算

select子句后不仅可接列名,还可接计算表达式或聚集函数,表明在投影的同时直接进行一些运算。

 

一、结果计算

1. 语法形式:select 列名 | expr | agfunc(列名) [[, 列名 | expr | agfunc(列名)] ... ] from 表名1 [, 表名2 ... ] [where 检索条件];

    ①expr:常量,列名,由常量、列名、特殊函数及算术运算符构成的算术运算式

    ②agfunc:聚集函数,如求平均、求和等

【示例1】求有差额(差额>0)的任意两位教师的薪水差额:

  • select T1.Tname as TR1, T2.Tname as TR2, T1.Salary - T2.Salary from Teacher T1, Teacher T2 where T1.Salary > T2.Salary;

【示例2】依据学生年龄求学生的出生年份,当前是2019年:

  • select S.S#, S.Sname, 2019 - S.Sage + 1 as Syear from Student S;

 

二、利用聚集函数进行统计计算

1. SQL提供了五个作用在简单列值集合上的内置聚集函数

聚集函数 功能描述
count (关于某列)求个数
sum (关于某列)求和
avg (关于某列)求平均
max (关于某列)求最大值
min (关于某列)求最小值

 

 

 

 

 

 

 

 

 

【示例1】求教师工资的总额:

  • select sum(Salary) from Teacher;

【示例2】求计算机系教师工资的总额:

  • select sum(Salary) from Teacher T, Dept where T.D# = Dept.D# and Dept.Dname = '计算机';

【示例3】求数据库课程的平均成绩:

  • select avg(Score) from SC, Course C where SC.C# = C.C# and C.Cname = '数据库';
  • 思考:此例只求了一门课程的平均成绩,那么如何求每一个学生或每一门课程的平均成绩呢?

 

三、分组查询

1. 分组:SQL可以将检索到的元组按照某一条件进行分类,具有相同具有相同条件值的元组划到一个组或一个集合中,同时处理多个组或集合的聚集运算。

    ①基本语法形式:select 列名 | expr | agfunc(列名) [[, 列名 | expr | agfunc(列名)] ... ] from 表名1 [, 表名2 ... ] [where 检索条件] [group by 分组条件];

    ②分组条件:单个列名或者多个列名

【示例1】求每一个学生的平均成绩:

  • select S#, avg(Score) from SC group by S#;  // 按学号进行分组,于是学号相同的元组被划到同一个组中并求平均值

【示例2】求每一门课程的平均成绩:

  • select C#, avg(Score) from SC group by C#;  // 按课号进行分组,于是课号相同的元组被划到同一个组中并求平均值

【示例3】求不及格课程超过两门的同学的学号:

  • select S# from SC where Score < 60 and count(*) > 2 group by S#;
  • 思考:该句并不正确,主要原因是聚集函数count(*)不能出现在where子句中
  • 因为where子句是对每一个元组进行条件过滤,而聚集函数则是对一个分组进行条件过滤,故聚集函数不应出现

 

四、分组过滤

1. 分组过滤的定义:对分组进行条件过滤,即满足条件的分组留下,不满足条件的分组过滤

 

2. having子句(分组过滤子句)

    ① 在分完组之后,用having子句来判断哪些分组保留,故需要有group by子句支持

    ②语法形式:select 列名 | expr | agfunc(列名) [[, 列名 | expr | agfunc(列名)] ... ] from 表名1 [, 表名2 ... ] [where 检索条件] [group by 分组条件 [having 分组过滤条件]];

    ③语义:把满足分组过滤条件的分组保留下来,把不满足分组过滤条件的分组过滤掉

【示例1】求不及格课程超过两门的同学的学号:

  • select S# from SC where Score < 60 group by S# having count(*) > 2
  • "having count(*) > 2"检查每个分组中元组的个数是否大于2,并将元组个数大于2的分组保留下来

【示例2】求有10人以上不及格的课程号:

  • select C# from SC where Score < 60 group by C# having count(*) > 10;

【示例3】having子句与where子句表达条件的区别:

  • 对每一元组检查满足与否的条件要用where子句表达
  • 对每一分组检查满足与否的条件要用having子句表达

 

posted @ 2019-04-20 20:38  GGBeng  阅读(810)  评论(0编辑  收藏  举报