group by 的实现原理

筅森魡賤 提交于 2020-01-10 20:50:41

转载: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条记录

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!