为啥我们要使用开窗函数?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥我们要使用开窗函数?相关的知识,希望对你有一定的参考价值。

参考技术A

什么时候会用到开窗函数呢?下面介绍使用场景:
表test1数据如下:

现在我们有需求:查出它们每个年级(class)的平均分数,预期结果格式如下:

我们可以看到,根据年级class求avg()聚合后的 数据会变少一条 ,但是,我们 既要显示聚合前的数据又要显示聚合后的数据 ,这个时候就要使用开窗函数。

测试:

查询数据:

返回结果:

出现的两个问题:
1.如果我们在partition by class加一个order by id会出现什么问题

返回结果:

可以看到class为1的两条avg值不一致,这是因为order by id是来一条数据处理一条,所以第一条class为1的数据来的只能是99/1=99。

我们可能会这样想,先查询出数据放到一张临时表,然后在开窗,根据class分区,再根据id排序,可是结果并不是根据id全局有序的
返回结果:

因为它是按照分区排序的,所以是分区内有序。

另外,我们和group by分组做个对比
原始数据如下

我们可能会想,为什么同样在这里使用了聚合函数sum(),数据条数变少了,我们为什么没有开窗呢?
这里使用group by进行了分组,根据id和时间进行分组。
那我们想是否上面也可以使用group by 而不使用开窗呢?
如下sql是否可以呢?

返回结果:

答案是不可以。因为我们select了多个字段,所以我们要根据多个字段来分组,class相同再根据id分组,id相同再根据score分组。导致我们不能仅仅根据class分组,也就导致最后分组出来的数据除了class、id、score都相同的两条数据能够聚合,否则都是单条数据自己聚合。
所以我们要使用group by就只能选取单个字段

返回结果

开窗函数over()

使用方法

如:select nameavgshengaofrom xinxi group by name

//我们都知道使用聚合函数要使用分组,如果不分组怎么办

Selct name,avg(shengao) over() from xinxi

不使用group by 就要使用开窗 否则报错

 

Name

Shengao

无名列

杜伟

180

170

徐哈风

160

170

以上是关于为啥我们要使用开窗函数?的主要内容,如果未能解决你的问题,请参考以下文章

开窗函数over()

开窗函数

SQL开窗函数

大数据之Hive:Hive 开窗函数

sql中的 开窗函数over() 聚合函数 排名函数

mysql开窗函数