使用方法
如:select name,avg(shengao)from xinxi group by name
//我们都知道使用聚合函数要使用分组,如果不分组怎么办
Selct name,avg(shengao) over() from xinxi
不使用group by 就要使用开窗 否则报错
Name |
Shengao |
无名列 |
杜伟 |
180 |
170 |
徐哈风 |
160 |
170 |
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就只能选取单个字段
返回结果
使用方法
如:select name,avg(shengao)from xinxi group by name
//我们都知道使用聚合函数要使用分组,如果不分组怎么办
Selct name,avg(shengao) over() from xinxi
不使用group by 就要使用开窗 否则报错
Name |
Shengao |
无名列 |
杜伟 |
180 |
170 |
徐哈风 |
160 |
170 |
以上是关于为啥我们要使用开窗函数?的主要内容,如果未能解决你的问题,请参考以下文章