分享

Excel VBA ADO SQL入门教程010:分组聚合

 L罗乐 2018-02-25

诸君好,又见面了……

1.

我们今天讲分组聚合。

先说分组。

分组这个概念其实大家并不陌生,在日常生活和数据分析过程中经常遇到,比如说,把公司的员工按部门分组,把身边的朋友按男女分组(也就是你的男朋友和你的女朋友啦)……等等。

在SQL中,创建分组一般是使用GROUP BY子句。

举个例子,下图是一张表名为成绩表的表格。

如果按班级分组:

SELECT 班级 FROM [成绩表$] GROUP BY 班级

结果如下:

如果按班级和学科两个类别进行分组:

SELECT 班级,学科 FROM [成绩表$] GROUP BY 班级,学科

结果如下

看到这儿,有朋友会说,什么分组,不就是去重查询吗?上面两个问题和去重查询没啥区别呀。

SELECT DISTINCT 班级,学科 FROM [成绩表$]

酱紫也可以啦~

……

是的,所谓分组,也就是去除重复值,把相同值归类保留唯一;因此GROUP BY也有去重复的疗……功效。阿呸,舌尖3看多了我~

但分组通常并不是目的,目的是分组后的聚合。关于聚合,也就是聚合函数,我们上节分享过了,戳链接:Excel VBA ADO SQL入门教程009:聚合函数

……

陈独秀老师告诉我,分组 聚合=分组聚合。

比如……

如果我们需要查询每个班级的成绩总分;很明显,班级是需要分组的,总分是需要聚合的,因此语句如下:

SELECT 班级,SUM(成绩) AS 总分 FROM [成绩表$] GROUP BY 班级

如果我们需要查询每个班级每个学科的成绩总分:

SELECT 班级,学科,SUM(成绩) AS 总分 FROM [成绩表$] GROUP BY 班级,学科

……

……

484很简单?

但需要说明的是,SELECT后的字段,必须包含在分组子句中,例如上述示例中的班级和学科。如果不包含其中,比如成绩,则必须使用聚合函数。

例如以下语句,学科既不存在GROUP BY子句中,也未使用聚合函数,则代码会得到错误的提示信息。

SELECT 班级,学科 FROM [成绩表$] GROUP BY 班级


2.

凡事最好有个条件,毕竟咱不是随便的人。

很多时候,用户并不需要所有的分组聚合的数据,只是需要其中一部分满足特定条件的;为此,SQL提供了HAVING子句。

比如,我们需要查询各个班级学科为语文的总分。

SELECT 班级,学科,SUM(成绩) AS 总分 FROM [成绩表$] GROUP BY 班级,学科 HAVING 学科='语文'

再比如,我们需要查询班级总分大于250的班级名单。

SELECT 班级,SUM(成绩) AS 总分 FROM [成绩表$] GROUP BY 班级 HAVING SUM(成绩)>250

需要注意的是,HAVING SUM(成绩)>250不能写成HAVING 总分>250,至于缘故,我们下期会讲到。

HAVING子句通常都是搭配GROUP BY分组语句出现的,用于在后者分组的基础上搜索相关条件,但这并不是说它只能依靠GROUP BY才能生存,它也可以单独存在。

例如以下语句计算了‘插班生‘的总分数。

SELECT SUM(成绩) AS 总分 FROM [成绩表$]  HAVING 班级='插班生'

当然,尽管HAVING可以单独生存,但在实际情况中却很少见;一方面,它单独出现时,能力非常有限,另一方面,我们还有WHERE子句。

……

打个响指,问题来了。

同样都是用于条件筛选,既生瑜何生亮?HAVING子句和WHERE子句有什么相同和不同之处?

相同之处在于,两则都可以定义搜索条件。

比如,前面讲的查询各个班级学科为语文的总分,既可以先分组后HAVING筛选,也可以先WHERE筛选后分组。

SELECT 班级,学科,SUM(成绩) AS 总分 FROM [成绩表$] GROUP BY 班级,学科 HAVING 学科='语文'

也可以写成:

SELECT 班级,学科,SUM(成绩) AS 总分 FROM [成绩表$] WHERE 学科='语文' GROUP BY 班级,学科 

此外,前面章节所介绍的WHERE子句的所有操作技巧,比如使用连接符、通配符、函数等,HAVING函数也都可以使用,相关技巧参考:

Excel VBA ADO SQL入门教程007:条件查询(上)

Excel VBA ADO SQL入门教程008:条件查询(下)

……

不同之处……

首先,运算顺序不同,WHERE优先于HAVING。

其次,作用对象不同。WHERE只作用于表,而HAVING作用于GROUP BY子句的分组结果,如果不存在GROUP BY子句,则作用于WHERE子句的搜索结果,如果WHERE子句也不存在,则直接作用于表。

最后,最重要的是,计算对象不同。HAVING是用于组的计算,WHERE则计算指定字段的每条记录。

例如我们需要查询成绩大于90分的学员名单。

语句可以写成:

SELECT 班级,姓名,学科,成绩 FROM [成绩表$]  WHERE 成绩>90

但不能写成:

SELECT 班级,姓名,学科,成绩 FROM [成绩表$]  HAVING 成绩>90

后者会出现错误提示:

同样的道理,我们要查询班级总分大于250的班级名单。

语句可以写成:

SELECT 班级,SUM(成绩) AS 总分 FROM [成绩表$] GROUP BY 班级 HAVING SUM(成绩)>250

但不能写成:

SELECT 班级,SUM(成绩) AS 总分 FROM [成绩表$] WHERE SUM(成绩)>250 GROUP BY 班级 

后者会出现错误提示:

……

……

……王宝强的唐仁真的有毒,我现在满脑海都是他说话的腔调和模样,无奈……

就酱紫吧~拥安~

图文作者:看见星光

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多