分组原理(GROUP BY子句)1:GROUP BY子句基本语法规则

分组原理(GROUP BY子句)1:GROUP BY子句基本语法规则

若觉得本文写得还可以,请多多关注本人所作书籍《C++语法详解》电子工业出版社出版,作者 黄勇,网盘地址:
https://pan.baidu.com/s/1dIxLMN5b91zpJN2sZv1MNg

本文为原创文章,转载请注明出处,或注明转载自“黄邦勇帅(原名:黄勇)

本小节需要使用聚合函数,聚合函数用于对一组值执行计算,并返回单个值,聚合函数只能用于SELECT语句的选择列表和HAVING子句中作为表达式使用,通常,聚合函数与GROUP BY子句一起使用。使用聚合函数的表达式被称为聚合表达式。比如SUM()用于求合,其用法如下,聚合函数的详细规则及使用,详见后文

SELECT SUM(b) FROM T3		--将输出表T3.b这一列中所有值的和

一、GROUP BY子句基本语法规则
1、GROUP BY用于把该子句之前逻辑阶段处理后的查询结果进行分组,在完整的SELECT语句中,GROUP BY子句在第5阶段被处理。
2、GROUP BY子句的基本语法(非完整)如下:

GROUP BY column-expression [ ,...n ]   --column-expression表示分组列

3、column-expression(分组列)的要求如下(详见示例):
 分组列必须是列或列上的非聚合计算,也就是说,分组列可以是表达式,但该表达式必须引用列(比如,不能引用常量),并且不能是聚合表达式(即,使用聚合函数)。
 分组列不能是子查询,也不能是索引视图中的列。
 分组列必须出现在SELECT语句的FROM子句中,但不需要出现在SELECT的选择列表中。也就是说,分组列必须是FROM子句中指定的表的列名,不能是来自外部引用的列名。
4、使用GROUP BY子句时的其他重要规则
 若使用了GROUP BY子句,则逻辑处理顺序在GROUP BY阶段之后的所有子句(包括、HAVING、SELECT、ORDER BY等)的操作对象都将是组,而不再是单独的行,SELECT语句的查询结果也只会为每个组返回一行。也就是说,在GROUP BY阶段之后的子句中的所有表达式务必保证为每个组只返回一个标量值(即单值)。
 SELECT选择列表中的列必须包含在GROUP BY子句的分组列表中,除非选择列是聚合表达式(因为聚合函数可保证返回的值是单一的),比如选择列使用聚合函数,或者把未在分组列表中的列作为聚合函数的参数。
 若分组列包含NULL值,则所有的 NULL 值都被视为相等,并置入同一个组中。
 另外,还应注意各子句的逻辑处理顺序,比如,分组列不能是SELECT选择列表中定义的列别名(因为SELECT子句位于GROUP BY子句之后执行),但可以是FROM子句中定义的派生表的列别名(因为FROM子句先于GROUP BY子句执行)。
 下面以示例讲解分组的原理及SELECT语句的输出规则,语句如下,输出结果及表T3的内容见图XXX

SELECT a FROM T3 GROUP BY a

由于SELECT选择列表的列必须包含在分组列表之中(聚合表达式除外),因此SELECT语句只能输出由GROUP BY子句分组列表中指定的列的内容(含聚合表达式的列除外),若某一组包含多行(如图XXX的分组4),由于SELECT选择列表中的列是参与了分组的(如图XXX,选择列表中的列只能是列a),因此只能输出这些参与了分组的列,但因为这些列所在行的值是相同的且位于同一组(如图XXX,分组4列a的两行的值是相同的,并位于同一组),因此,SELECT语句只需输出其中的一行即可,这样就保证了SELECT语句只输出分组中的一行,输出结果如图XXX所示,其中分组4将只会输出一行(值为4的行),不会输出两行。注意,若语句修改为

SELECT a FROM T3 GROUP BY a,b

即,使用列a和列b对表T3进行分组,则会输出两行值为4的行,因为此时(4, 44, 444)与(4, 441, 4441)两行现在被分为两组了,他们不在同一组了,因此两组都会被输出。
在这里插入图片描述

示例5.01:GROUP BY分组列的基本要求(表T3包含a, b, x共三列)
--SELECT a FROM T3 GROUP BY 3+4		--错误,分组列没有引用表的列
--SELECT a FROM T3 GROUP BY SUM(a)		--错误,分组列不能是聚合表达式(SUM是聚合函数)
SELECT 3+a as S FROM T3 GROUP BY 3+a	--正确,表达式3+a引用了表的列名
--SELECT b FROM T3 GROUP BY (SELECT b from T3 where a=1)	--错误,分组列不能是子查询
SELECT a FROM T3 GROUP BY a,b			--正确,分组列不必出现在SELECT的选择列表中

示例5.02:选择列与分组列的关系(表T3包含a, b, x共三列)
 --重点理解选择列表中的列包含在分组列表中的意思,以下为一些示例
--SELECT b FROM T3 GROUP BY a			--错误,SELECT选择列表中的列b未在分组列表中
SELECT a,SUM(3) FROM T3 GROUP BY a 	--正确,选择列可以是聚合表达式(即SUM(3))
--SELECT * FROM T3 GROUP BY a,b		--错误,*表示所有列,其中列x不在分组列表中
SELECT 3+a FROM T3 GROUP BY a			--正确,选择列3+a使用的列a包含在分组列表中
--SELECT a FROM T3 GROUP BY 3+a		--错误,分组列表中的列为(3+a)
--SELECT a+3 FROM T3 GROUP BY 3+a		--错误,同上,注意:这里3+a与a+3并不相同
SELECT 3+a+4 FROM T3 GROUP BY 3+a		--正确
--SELECT 1+2+a FROM T3 GROUP BY 3+a	--错误
--SELECT 4+3+a FROM T3 GROUP BY 3+a	--错误,但把3+a加上括号就是正确的,如下
SELECT 4+(3+a) FROM T3 GROUP BY 3+a	--正确
SELECT a+b FROM T3 GROUP BY a,b		--正确
--SELECT a FROM T3 GROUP BY a+b		--错误,分组列表中的列为(a+b),而不是a和b
--SELECT b+a FROM T3 GROUP BY a+b		--错误,同上

示例5.03:使用GROUP BY子句分组后的效果(输出结果见图)
SELECT sum(b) AS sb FROM T3 				--语句1,SUM是聚合函数,用于对列进行求和
SELECT a,sum(b)AS sb FROM T3 GROUP BY a	--语句2

在这里插入图片描述
示例XXX的说明:
1、以上示例运行原理,如图XXX所示,语句2按照列a的值把表T3的行分成了6组,其中第4组包含两行内容,其余的组都只包含一行的内容
2、在未进行分组时(即语句1),对b列进行求和,得到的是列b所有行(共7行)的值的和,当进行分组后(即语句2),对b列进行求和得到的是每个组中(即以组为对象)b列所有行的值的和。比如,分组4,包含两行,对b列进行求和,将只对这两行的值进行求和,但对于该分组,SELECT语句只输出一行,即列a的值为4的行。由于其余分组都只有一行内容,因此对b列求和的结果就是该行的值。

示例5.04:GROUP BY实际应用(求出每年的总销量,输出结果见图XXX)

SELECT YEAR(日期) AS 年分,SUM(销量) AS 年销量 FROM T6 GROUP BY YEAR(日期)

在这里插入图片描述

作者:黄邦勇帅(原名:黄勇)

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/hyongilfmmm/article/details/93891020