SQL语句:GroupBy总结

更新时间:2023-05-19 08:13:27 阅读: 评论:0

SQL语句:GroupBy总结
1. Group By 语句简介:
Group By语句从英⽂的字⾯意义上理解就是“根据(by)⼀定的规则进⾏分组(Group)”。它的作⽤是通过⼀定的规则将⼀个数据集划分成若⼲个⼩的区域,然后针对若⼲个⼩区域进⾏数据处理。
P.S. 这⾥真是体会到了⼀个好的命名的⼒量,Group By从字⾯是直接去理解是⾮常好理解的。恩,以后在命名的环节⼀定要加把劲:)。话题扯远了。occasion
2. Group By 的使⽤:
上⾯已经给出了对Group By语句的理解。基于这个理解和SQL Server 2000的联机帮助,下⾯对Group By语句的各种典型使⽤进⾏依次列举说明。
2.1 Group By [Expressions]:
这个恐怕是Group By语句最常见的⽤法了,Group By + [分组字段](可以有多个)。在执⾏了这个操作以后,数据集将根据分组字段的值将⼀个数据集划分成各个不同的⼩组。⽐如有如下数据集,其中⽔果名称(FruitName)和出产国家(ProductPlace)为联合主键:
FruitName ProductPlace Price
Apple China$1.1
Apple Japan$2.1
Apple USA$2.5
Orange China$0.8
Banana China$3.1
Peach USA$3.0
如果我们想知道每个国家有多少种⽔果,那么我们可以通过如下SQL语句来完成:
SELECT COUNT(*)AS⽔果种类,ProductPlace AS出产国
FROM T_TEST_FRUITINFO
GROUPBY ProductPlace
这个SQL语句就是使⽤了Group By + 分组字段的⽅式,那么这句SQL语句就可以解释成“我按照出产国家(ProductPlace)将数据集进⾏分组,然后分别按照各个组来统计各⾃的记录数量。”很好理解对吧。这⾥值得注意的是结果集中有两个返回字段,⼀个是ProductPlace(出产国), ⼀个是⽔果种类。如果我们这⾥⽔果种类不是⽤Count(*),⽽是类似如下写法的话:
SELECT FruitName,ProductPlace FROM T_TEST_FRUITINFO GROUPBY ProductPlace
那么SQL在执⾏此语句的时候会报如下的类似错误:四级考试分值
选择列表中的列'T_TEST_FRUITINFO.FruitName'⽆效,因为该列没有包含在聚合函数或GROUPBY⼦句中。
这就是我们需要注意的⼀点,如果在返回集字段中,这些字段要么就要包含在Group By语句的后⾯,作为分组的依据;要么就要被包含在聚合函数中。我们可以将Group By操作想象成如下的⼀个过程,⾸先系统根据SELECT 语句得到⼀个结果集,如最开始的那个⽔果、出产国家、单价的⼀个详细表。然后根据分组字段,将具有相同分组字段的记录归并成了⼀条记录。这个时候剩下的那些不存在于Group By语句后⾯作为分组依据的字段就有可能出现多个值,但是⽬前⼀种分组情况只有⼀条记录,⼀个数据格是⽆法放⼊多个数值的,所以这⾥就需要通过⼀定的处理将这些多值的列转化成单值,然后将其放在对应的数据格中,那么完成这个步骤的就是聚合函数。这就是为什么这些函数叫聚合函数(
aggregate functions)了。
2.2 Group By All [expressions] :
Group By All + 分组字段, 这个和前⾯提到的Group By [Expressions]的形式多了⼀个关键字ALL。这个关键字只有在使⽤了where语句的,且where条件筛选掉了⼀些组的情况才可以看出效果。在SQL Server 2000的联机帮助中,对于Group By All是这样进⾏描述的:
如果使⽤ALL关键字,那么查询结果将包括由GROUPBY⼦句产⽣的所有组,即使某些组没有符合搜索条件的⾏。没有ALL关键字,包含GROUPBY⼦句的SELECT语句将不显⽰没有符合条件的⾏的组。
其中有这么⼀句话“如果使⽤ALL关键字,那么查询结果将包含由Group By⼦句产⽣的所有组...没有ALL关键字,那么不显⽰不符合条件的⾏组。”这句话听起来好像挺⽿熟的,对了,好像和LEFT JOIN 和 RIGHT JOIN 有点像。其实这⾥是类⽐LEFT JOIN来进⾏理解的。还是基于如下这样⼀个数据集:
FruitName ProductPlace Price
Apple China$1.1
Apple Japan$2.1
Apple USA$2.5
Orange China$0.8
Banana China$3.1
perfect意思Peach USA$3.0
⾸先我们不使⽤带ALL关键字的Group By语句:
SELECT COUNT(*)AS⽔果种类,ProductPlace AS出产国
FROM T_TEST_FRUITINFO
WHERE(ProductPlace<>'Japan')
GROUPBY ProductPlace
那么在最后结果中由于Japan不符合where语句,所以分组结果中将不会出现Japan。
现在我们加⼊ALL关键字:
SELECT COUNT(*)AS⽔果种类,ProductPlace AS出产国
FROM T_TEST_FRUITINFO
WHERE(ProductPlace<>'Japan')
GROUPBY ALL ProductPlace
重新运⾏后,我们可以看到Japan的分组,但是对应的“⽔果种类”不会进⾏真正的统计,聚合函数会根据返回值的类型⽤默认值0或者N ULL来代替聚合函数的返回值。
2.3 GROUP BY [Expressions] WITH CUBE | ROLLUP:
⾸先需要说明的是Group By All 语句是不能和CUBE 和 ROLLUP 关键字⼀起使⽤的。
⾸先先说说CUBE关键字,以下是SQL Server 2000联机帮助中的说明:
指定在结果集内不仅包含由GROUPBY提供的正常⾏,还包含汇总⾏。在结果集内返回每个可能的组和⼦组组合的GROUPBY汇总⾏。GR OUPBY汇总⾏在结果中显⽰为NULL,但可⽤来表⽰所有值。使⽤GROUPING函数确定结果集内的空值是否是GROUPBY汇总值。
结果集内的汇总⾏数取决于GROUPBY⼦句内包含的列数。GROUPBY⼦句中的每个操作数(列)绑定在分组NULL下,并且分组适⽤于所有其它操作数(列)。由于CUBE返回每个可能的组和⼦组组合,因此不论指定分组列时所使⽤的是什么顺序,⾏数都相同。
我们通常的Group By语句是按照其后所跟的所有字段进⾏分组,⽽如果加⼊了CUBE关键字以后,那么系统将根据所有字段进⾏分组的基础上,还会通过对所有这些分组字段所有可能存在的组合形成的分组条件进⾏分组计算。由于上⾯举的例⼦过于简单,这⾥就再适合了,现在我们的数据集将换⼀个场景,⼀个表中包含⼈员的基本信息:员⼯所在的部门编号(C_EMPLINFO_DEPTID)、员⼯性别(C_EMPLINFO_SEX)、员⼯姓名(C_EMPLINFO_NAME)等。那么我现在想知道每个部门各个性别的⼈数,那么我们可以通过如下语句得到:
SELECT C_EMPLINFO_DEPTID,C_EMPLINFO_SEX,COUNT(*)AS C_EMPLINFO_TOTALSTAFFNUM
FROM T_PERSONNEL_EMPLINFO
GROUPBY C_EMPLINFO_DEPTID,C_EMPLINFO_SEX
但是如果我现在希望知道:疫情英语
1. 所有部门有多少⼈(这⾥相当于就不进⾏分组了,因为这⾥已经对员⼯的部门和性别没有做任何限制了,但是这的确也是⼀种分组条件的组合⽅式);
2. 每种性别有多⼈(这⾥实际上是仅仅根据性别(C_EMPLINFO_SEX)进⾏分组);
3. 每个部门有多少⼈(这⾥仅仅是根据部门(C_EMPLINFO_DEPTID)进⾏分组);那么我们就可以使⽤ROLLUP语句了。
SELECT C_EMPLINFO_DEPTID,C_EMPLINFO_SEX,COUNT(*)AS C_EMPLINFO_TOTALSTAFFNUM
FROM T_PERSONNEL_EMPLINFO
GROUPBY C_EMPLINFO_DEPTID,C_EMPLINFO_SEX WITH CUBE
那么这⾥你可以看到结果集中多出了很多⾏,⽽且结果集中的某⼀个字段或者多个字段、甚⾄全部的字段都为NULL,请仔细看⼀下你就会发现实际上这些记录就是完成了上⾯我所列举的所有统计数据的展现。使⽤过SQL Server 2005或者RDLC的朋友们⼀定对于矩阵的⼩计和分组功能有印象吧,是不是都可以通过这个得到答案。我想R DLC中对于分组和⼩计的计算就是通过Group By的CUBE和ROLLUP关键字来实现的。(个⼈意见,未证实)
CUBE关键字还有⼀个极为相似的兄弟ROLLUP, 同样我们先从这英⽂⼊⼿,ROLL UP是“向上卷”的意思,如果说CUBE的组合是绝对⾃由的,那么ROLLUP的组合就需要有点约束了。我们先来看看SQL Server 2000的联机中对ROLLUP关键字的定义:
指定在结果集内不仅包含由GROUPBY提供的正常⾏,还包含汇总⾏。按层次结构顺序,从组内的最低级别到最⾼级别汇总组。组的层次结构取决于指定分组列时所使⽤的顺序。更改分组列的顺序会影响在结果集内⽣成的⾏数。
那么这个顺序是什么呢?对了就是Group By 后⾯字段的顺序,排在靠近Group By的分组字段的级别⾼,然后是依次递减。如:Group By Column1, Column2, Column 3。那么分组级别从⾼到低的顺序是:Column1 > Column2 > Column3。还是看我们前⾯的例⼦,SQL语句中我们仅仅将CUBE关键字替换成ROLLUP关键字,如:
SELECT C_EMPLINFO_DEPTID,C_EMPLINFO_SEX,COUNT(*)AS C_EMPLINFO_TOTALSTAFFNUM
aislesFROM T_PERSONNEL_EMPLINFO
GROUPBY C_EMPLINFO_DEPTID,C_EMPLINFO_SEX WITH ROLLUP
和CUBE相⽐,返回的数据⾏数减少了不少。:),仔细看⼀下,除了正常的Group By语句后,数据中还包含了:
1. 部门员⼯数;(向上卷了⼀次,这次先去掉了员⼯性别的分组限制)
2. 所有部门员⼯数;(向上⼜卷了依次,这次去掉了员⼯所在部门的分组限制)。
在现实的应⽤中,对于报表的⼀些统计功能是很有帮助的。
这⾥还有⼀个问题需要补充说明⼀下,如果我们使⽤ROLLUP或者CUBE关键字,那么将产⽣⼀些⼩计的⾏,这些⾏中被剔除在分组因素之外的字段将会被设置为NUL L,那么还存在⼀种情况,⽐如在作为分组依据的列表中存在可空的⾏,那么NULL也会被作为⼀个分组表⽰出来,所以这⾥我们就不能仅仅通过NULL来判断是不是⼩计记录了。下⾯的例⼦展⽰了这⾥说得到的情况。还是我们前⾯提到的⽔果例⼦,现在我们在每种商品后⾯增加⼀个“折扣列”(Discount),⽤于显⽰对应商品的折扣,这个数值是可空的,也就是可以通过NULL来表⽰没有对应的折扣信息。数据集如下所⽰:
FruitName ProductPlace Price Discount
Apple China$1.10.8
Apple Japan$2.10.9
Apple USA$2.5  1.0
Orange China$0.8NULL
Banana China$3.1NULL
Peach USA$3.0NULL
现在我们要统计“各种折扣对应有多少种商品,并总计商品的总数。”,那么我们可以通过如下的SQL语句来完成:苦闷
SELECT COUNT(*)AS ProductCount,Discount
FROM T_TEST_FRUITINFO
GROUPBY Discount WITH ROLLUPagain是什么意思译
好了,运⾏⼀下,你会发现数据都正常出来了,按照如上的数据集,结果如下所⽰:
ProductCount Discount
3NULL
10.8
10.9
1  1.0
6NULL
好了,各种折扣的商品数量都出来了,但是在显⽰“没有折扣商品”和“商品⼩计”的时候判断上确存在问题,因为存在两条Discount为Null的记录。是哪⼀条呢?通过分析数据我们知道第⼀条数据(3, Null)应该对应没有折扣商品的数量,⽽(6,Null)应该对应所有商品的数量。需要判断这两个具有不同意义的Null就需要引⼊⼀个聚合函数Grouping 。现在我们把语句修改⼀下,在返回值中使⽤Grouping函数增加⼀列返回值,SQL语句如下:
SELECT COUNT(*)AS ProductCount,Discount,GROUPING(Discount)AS Expr1
照片英文
FROM T_TEST_FRUITINFO
GROUPBY Discount WITH ROLLUP
这个时候,我们再看看运⾏的结果:
ProductCount Discount Expr1
3NULL0
10.80
10.90
淘汰的英文
1  1.00
6NULL1
对于根据指定字段Grouping中包含的字段进⾏⼩计的记录,这⾥会标记为1,我们就可以通过这个标记值将⼩计记录从判断那些由于ROLLUP或者CUBE关键字产⽣的⾏。Grouping(column_name)可以带⼀个参数,Grouping就会去判断对应的字段值的NULL是否是由ROLLUP或者CUBE产⽣的特殊NULL值,如果是那么就在由Grouping聚合函数产⽣的新列中将值设置为1。注意Grouping只会检查Column_name对应的NULL来决定是否将值设置为1,⽽不是完全由此列是否是由ROLLUP或者CUBE关键字⾃动添加来决定的。
2.2Group By 和 Having, Where ,Order by语句的执⾏顺序:
最后要说明⼀下的Group By, Having, Where, Order by⼏个语句的执⾏顺序。⼀个SQL语句往往会产⽣多个临时视图,那么这些关键字的执⾏顺序就⾮常重要了,因为你必须了解这个关键字是在对应视图形成前的字段进⾏操作还是对形成的临时视图进⾏操作,这个问题在使⽤了别名的视图尤其重要。以上列举的关键字是按照如下顺序进⾏执⾏的:Where, Group By, Having, Order by。⾸先where将最原始记录中不满⾜条件的记录删除(所以应该在where语句中尽量的将不符合条件的记录筛选掉,这样可以减少分组的次数),然后通过Group By关键字后⾯指定的分组条件将筛选得到的视图进⾏分组,接着系统根据Having关键字后⾯指定的筛选条件,将分组视图后不满⾜条件的记录筛选掉,然后按照Order By语句对视图进⾏排序,这样最终的结果就产⽣了。在这四个关键字中,只有在Order By语句中才可以使⽤最终视图的列名,如:
SELECT FruitName,ProductPlace,Price,ID AS IDE,Discount
FROM T_TEST_FRUITINFO
上海高中辅导WHERE(ProductPlace=N'china')
ORDERBY IDE
这⾥只有在ORDER BY语句中才可以使⽤IDE,其他条件语句中如果需要引⽤列名则只能使⽤ID,⽽不能使⽤IDE。

本文发布于:2023-05-19 08:13:27,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/114312.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:分组   结果   语句   关键字   字段   数据   条件   包含
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图