转载:https://cloud.tencent.com/developer/article/1513067
写过 Sql 的同学应该都知道 group by 是用来对数据进行分组的,一般与聚合函数一起使用,对分组后的数据进行聚合。虽然大家都在用,但是有些同学还是不太清楚 group by 的底层到底是如何实现分组并且最后进行聚合的。今天就讲讲 group by 的底层实现。
我们直接来看例子,下面有一张表 t,存储了不同日期对应的不同品类的销量,具体数据如下:
现在我们要统计2019年1月1到1月3期间没每个品类的总销量,这个需求我们就可以用 group by 来实现,实现代码如下:
select cat ,sum(sales) from t where sale_date between "2019/1/1" and "2019/1/3" group by cat
上面代码中的 group by 具体执行过程是什么样子的呢?我们看一下下面这这张图。
通过上图我们可以看出 group by 会对所有的数据先根据 cat 字段进行分组,然后针对分组后的数据在组内进行聚合运算(计数、求和、求均值等),最后再将聚合后的每组数据进行汇总就得到了我们想要的结果。在上图中大家应该看到了分组模块只有 cat 这一列是标红加粗,sale_date 和 sales 这两列是比较虚的字体,为什么会这样呢?难道我写错了?其实不然,是我故意的。为什么要故意呢?我们看一下下面这张图:
上图是将表 t 在 Excel 中做一个数据透视表,如果我们只将 cat 这一列拖到行区域的时候,在表中只显示出了 cat 这一列,别的列是没有显示出来的,Sql 中也是一样的道理,所以我们只有 cat 列是标红加粗显示,而其他列是虚的,是因为其他列在这个阶段是没有显示出来,不过他们也是随时待命的状态。
一旦你指明了要按照哪列数据进行聚合,他们就会按照事先分好的组对要聚合的列去进行相应的聚合运算,然后将结果进行汇总,就是我们想要的数据了。
上面的是最简单的一个例子,就是只按照 cat 这一列进行分组,如果我们现在想要同时对 cat 和 sale_date 这两列来进行分组的话该怎么实现呢?实现代码如下:
select cat ,sale_date ,sum(sales) from t where sale_date between "2019/1/1" and "2019/1/3" group by cat,sale_date
这个时候就相当于在透视表里面把 cat 和 sale_date 同时拖到了行区域,但是也是只显示这两列,而别的列是不显示的,只有指明了聚合列的时候,才会把聚合后的结果展示出来。
单纯的分组聚合的原理大家应该都明白了,不过这里有一个特别需要注意的点不知道大家有没有注意到,就是除了聚合列以外,select 后面要查询的列,必须在 group by 的后面出现。为什么要这样呢?通过上面的两个例子,我们也看到了,虽然一个数据表会有多列,但是在 group by 的时候,只会显示出来你 group by 的列,而其他列是不显示出来的,没有显示出来的列,你在 select 的时候肯定是查询不到的。
源数据如下:
按照c1, c2分组之后:
因为第1行和第6行属于同一个分组,因此只剩下5条记录
来源:CSDN
作者:一缕阳光a
链接:https://blog.csdn.net/zgaoq/article/details/103928175