分组查询主要是指Group By字句将行划分成较小的组,然后使用聚合函数返回每一组的汇总信息。分组查询一般是用来满足统计需求的。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

1. 使用Group By进行分组查询

     为了说明分组查询来看以学生成绩表的例子,成绩表中存储了所有课程的成绩。在这种情况下,可能就需要不同课程的平均成绩,也就是说,需要对不同的成绩首先按照课程进行分组,分组以后再进行聚合计算,得到累计信息。
假设学员成绩表中有以下数据:
此时,要统计不同课程的平均分数,首先把相同的CourseID都分为一组,然后把这些相同对应的分数值在使用前面的聚合函数取平均值,如图所示:
以上这种类型的查询,在SQL server中叫做分组查询,分组查询采用Group By子句来实现。
采用分组查询的SQL语句如下:
Select CourseID, Avg(Score)  as 课程平均成绩
From Score
Group By CourseID
查询结果如图:
  分组查询有时候可能还要按照多个列进行分组。例如,成绩表中记录了每门课程内部测试的成绩。内部测试如果不及格还需要补考,补考学生最后的成绩取第一次成绩和补考成绩的平均值,如下图所示:
如果要统计内部测试的成绩表,则学生的编号、内部测试的课程编号不能存在重复,两项都重复的行的分数值要去平均值。因此,这是一个既按照学生编号又按照内部测试课程编号进行分组的查询。
SQL语句如下:
Select  StudentID as 学员编号,CourseID as 内部测试, Avg(Score) as 内部测试平均成绩
From Score
Group By StudentID,CourseID
查询输出的结果如下图:
要使用Group By关键字时,在select列表中可以指定的项目是有限的,select语句中仅允许以下几项。
被分组的列
为每个组返回一个值的表达式
2.使用Having子句进行分组筛选

案例需求:接上面的案例,如果查询内部测试的成绩,只显示补考过的学员的成绩怎么处理

这个时候,牵涉到分组统计后的条件限制。限制条件为Countscore>1必须要使用Having子句

满足以上要求的SQL语句如下:

Select StudentID as 学员编号,CourseID as 内部测试,

Avg(Score)  as 内部测试平均成绩

From Score

Group By StudentID,CourseID

Having Count(Score)>1

查询结果如图:

3.分组查询对比

WHERE子句从数据源中去掉不符合其搜索条件的数据

GROUP BY子句搜集数据行到各个组中,统计函数为各个组计算统计值

HAVING子句去掉不符合其组搜索条件的各组数据行

下面继续通过案例的形式讲解分组查询的具体应用过程。
案例需求1: 在按照部门分类的员工表中,要查询有多个员工的工资不低于2000 的部门编号
Select 部门编号, Count(*)
From 员工信息表
Where 工资 >= 2000
GROUP BY 部门编号
Having Count(*) > 1
案例需求2: 查询082月到7月的客户账单合计费用

Select CAST (DATEPART(YEAR,paytime) as varchar(10))+''+ CAST (DATEPART(MONTH,paytime) as varchar(10))+'' AS 日期,Sum(CHARGE) 合计费用
From "history-accountbill Where isPaid<>0 AND
paytime between '2008-02-01 00:00:00' and '2008-7-31 23:59:59'
Group By CAST (DATEPART(YEAR,paytime) as varchar(10))+''+ CAST (DATEPART(MONTH,paytime) as Varchar(10))+''