--group by 子句将查询结果进行按照一列或者多列的值进行分组,值相等的为一组--对查询结果进行分组的目的是为了进一步细化聚集函数的作用对象.--如果未对查查询结果进行分组,那么聚集函数将作用于整个查询结果,--分组后聚集函数将作用在每一个组上,即每一个组都有一个函数值--求各个课程号及选课的人数--该语句对从select Cno from SC表中查询到的结果按照课程号相同条件进行分组,分组后每个课程号可能对应多个--学生,这时候在对分组之后的结果作用聚集函数,统计每个课程号对应的课程选课的人数是多少,作用的对象是组--即每组都会产生一个函数值.select Cno
from SC;select Cno,count(*)
from SC
groupby Cno;select Cno,count(Cno)
from SC
groupby Cno;select Cno,count(Sno)
from SC
groupby Cno;--如果未对结果进行分组,使用聚集函数,这样聚集函数的作用对象是整个数据来源的基本表selectcount(*)
from SC;--这样显然也是不可以的,Cno在SC表中可能有多个值,但是count(*)是对表中的某个属性列进行聚集,形成单值select Cno,count(*)
from SC;--如果分组之后还需要对分组的结果进行筛选(过滤),最终只输出满足条件的组,这时候可以使用having短语来指定--筛选条件--查询选修了三门以上(包含)课程的学生学号--首先应该确定每个学生(每个学号)选修了多少门课程select Sno,count(*)
from SC
groupby Sno;--查询选修表的全部信息select *
from SC;--将对上面的结果进行再次筛选(过滤),选择选修课程数大于等于3门的学生学号select Sno
from SC
groupby Sno
havingcount(*)>=3;--该语句的执行过程是:首先SC表中的数据按照学生学号Sno进行分组,Sno相同的元组分到同一组中--然后执行having子句的时候,先对分组后的每一组作用聚集函数count(*),统计出每个学生选修课程的数量--最后对执行筛选条件,当一个学生选修的课程数是3门及3门以上的时候才会输出该学生的学号(没有就只输出Sno)select Sno
from SC
groupby Sno
havingcount(*)>3;--where子句和having子句的区别在哪里--where子句和having子句作用的对象不同,where子句是对整个基本表或者视图进行筛选(过滤),选出满足条件的元组--having子句同样可以进行筛选,但是having子句的作用对象是分组之后的每一个组,选出满足条件的组的信息;--where子句中是不能能使用聚集函数作为条件表达式的select Sno
from SC
groupby Sno
wherecount(*)>3;--查询出平均成绩大于或者等于90分的学生学号和成绩--这里的平均成绩指的是每个学生选修的所有课程的平均成绩--首先对学号(学号相同的元组分为一组)进行分组,确定每个学生(学生学号)选修的各个课程成绩,select Sno
from SC
groupby Sno;--然后对分组后的每一个组作用聚集函数avg(Grade)select Sno 学生学号,avg(Grade) 平均成绩
from SC
groupby Sno;--最后将分组后作用聚集函数的分组统计结果进行筛选,选择出满足条件的组的信息--在对最后的结果进行投影(选出我们需要看到的字段的时候),我们可以使用[as] 字段名对字段起别名select Sno 学生学号,avg(Grade) 平均成绩
from SC
groupby Sno
havingavg(Grade)>90;select Sno as 学生学号,avg(Grade) as 平均成绩
from SC
groupby Sno
havingavg(Grade)>80;--如果使用where子句对作用聚集函数之后的分组进行筛选:where子句中是不能使用聚集函数作为条件表达式的select Sno,avg(Grade)
from SC
groupby Sno
whereavg(Grade)>80;--对分组后结果进行投影的时候,select子句之后能出现分组后每个组的整体信息,而不能出现分组前的详细信息--错误提示不是Group by表达式select Cno
from SC
groupby Sno;select Grade
from SC
groupby Sno;select *
from SC
groupby Sno;