聚合函数和开窗函数

开窗函数

over在聚合函数中的使用:
一般格式:
聚合函数名(列) over(选项)
over必须与聚合函数或排序函数一起使用,聚合函数为:
sum(),max(),min(),count(),avg()
排序函数为:
rank(),row_number(),dense_rank(),ntile()
over表示把函数当成开窗函数而不是聚合函数,SQL标准允许将所有聚合函数用做开窗函数,使用over关键字来区分这两种用法。
开窗函数不需要使用group by就可以对数据进行分组,就可以同时返回基础行的列和聚合列。

开窗函数sum(*) over(),对于查询结果的每一行都返回所有符合条件的行的条数,over关键字后的括号中还经常添加选项来改变进行聚合运算的窗口范围,如果over关键字后的括号中选项为空,则开窗函数会对结果集中的所有行进行聚合运算。

常用格式:
sum(*) over(partition by A order by B)
partition by:进行分组,得到对应组内的所有求和值
order by:按照B进行排序,得到对应组内的累计求和值(如果B为id,两个id相同,则这两个id返回的sum那一列是相同的聚合值,是累计到最后一个id对应值的和–下面的例子会详细说明)

order by 字段名 rows|range between 边界规则1 and 边界规则2
rows:表示按照行的范围进行范围的定位
range:表示按照取值的范围进行范围的定位
这两种不同的定位方式主要用来处理并列排序的情况(见下面的例子)
边界规则的可取值为:
current row–当前行
n preceding–前n行
unbounded preceding–一直到第一条记录
n following–后n行
unbounded following–一直到最后一条记录
’range/rows between 边界规则1 and 边界规则2’:用来定位聚合计算范围,被称为定位框架。

eg:
1、建表

2、插入数据

3、关于partition by
(1)所属城市的人员数-按城市进行分组聚合

(2)显示每一个人员的信息、所属城市的人员数以及同龄人的人数

在同一个SELECT语句中可以同时使用多个开窗函数,而且这些开窗函数并不会相互干扰。
4、关于order by的详解:
(1)查询从第一行到当前行的的工资总和

(2)将上面的row换成range

结果和(1)的区别体现在红框和黄框部分,按照FSalary进行排序,row-按照行的范围进行范围定位,所以每一行后面对应的‘到当前行工资求和’都不一样,都严格的是第一行到当前行的累计和;range-按照取值的范围进行范围定位,虽然定位框架的语法仍然是从第一行到当前行的累计和,但是由于取值的范围:等于2000元的工资有3人,所以计算的累计为从第一条到2000元工资的最后一个人,写在每个2000元工资的人的后面都是7000。
(3)将(2)中的定位框架省略

上述框架是开窗函数中最常用的定位框架,如果是这种框架的话,可以省略上述定位框架部分

得到的结果和(2)的结果一样。
(4)将上面的sum()换成count(),计算工资排名

按照salary进行排序,然后计算从第一行(unbounded preceding)到当前行(current row)的人员的个数,相当于计算人员的的工资水平排名。
Question:
怎么让工资为2000元的排名都为2?–见后面排序函数的rank()和dence_rank()
5、关于over(partition by A order by B)

over在排序函数中的使用:
一般格式:
排序函数(列) over(选项)
排序函数为:
rank(),dense_rank(),row_number(),ntile(),lead(),lag()
1、rank(),dense_rank(),row_number()的区别

rank()与dense_rank()的区别:
两者都是计算一组数值中的排序值,
但是在有并列关系时,dence_rank中相关等级不会跳过,rank则跳过。
rank() 是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内)
dense_rank()是连续排序,有两个第二名时仍然跟着第三名。
row_number():
row_number over(partition by A order by B)
根据A分组,在分组内根据B排序,且得出来的值是每组内部排序后的顺序编号(组内连续的唯一的)
其主要是‘行’的信息,并没有排名。row_number()必须与order by一起使用,
多用于分页查询,比如查询10-100个学生。

2、ntile(x)–平均分区函数

3、lag() over(partition by A order by B)
lead() over(partition by A order by B)
lag和lead中有三个参数,lag(’列名’,offset,’超出记录窗口时的默认值’)
lag和lead可以获取,按一定顺序B排列的当前行的上下相邻若干offset的莫隔行的某个列。
lag()是向前,lead()是向后。

参考 https://www.cnblogs.com/lihaoyang/p/6756956.html

js判定是否传入回调函数

关于js回调函数,自己之前了解过,但是概念不是很清晰了,这里重新找几篇博客回顾一下概念,整理的感觉比较好的几个博客的总结的概念。方便复习。
js中的回调函数的理解:回调函数就是传递一个参数化函数,就是将这个函数作为一个参数传到另外一个主函数里面,当那个主函数执行完之后,再执行传递过去的函数,走这个过程的参数化的函数,就叫回调函数,换个说法也就是被作为参数传递到另一个函数(主函数)的那个函数就叫做回调函数。
回调函数:函数a有一个参数,这个参数是个函数b,当函数a执行完以后执行函数b。那么这个过程就叫回调。,这句话的意思是函数b以一个参数的形式传入函数a并执行,顺序是先执行a ,然后执行参数b,b就是所谓的回调函数。
function a(callback){
alert(’a’);
callback.call(this);//或者是 callback(), callback.apply(this),看个人喜好
}
function b(){ // 为回调函数。
alert(’b’);
}
//调用
a(b);
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
js中的回调函数:官方解释,当程序跑起来的时候,一般情况下,应用程序会时常通过API调用库里的所先预备好的函数,但是有些库函数,却要求应用先传给它的一个函数,好在适合的时候调用,以完成目标任务。这个被传入的,后又被调用的函数成为回调函数。
通常将一个函数B传入另外一个函数A,并且在需要的时候调用A.,说白了就是回溯函数,先定义好将要使用的函数体,饭后在使用在调用这个函数我们通常把callback作为一个参数传入定义的那个函数。下面我们看一段实现这个效果的js代码。
function Buy(name,goods1,callback) {
alert(name+’ buy ’+goods1);
if(callback&&typeof(callback)===“function“)
callback();
}
Buy(’xiaoming’,’apple’,function(){
alert(“shopping finish“);
});
1
2
3
4
5
6
7
8
1
2
3
4
5
6
7
8
一个简单的代码,一开始不知道要买啥,等到买东西的时候,立即把之前定义好的函数调用出来,最好加上判断,因为一切的前提是callback必须是一个函数,输出结果为:
xiaoming buy apple
shopping finish
1
2
1
2
这样应该能理解什么是回调函数了吧。
打开CSDN,阅读体验更佳
JS中的 回调函数(callback)_前端小草籽的博客_js回调函数
1.什么是回调函数(callback)呢? 把函数当作一个参数传到另外一个函数中,当需要用这个函数是,再回调运行()这个函数. 回调函数是一段可执行的代码段,它作为一个参数传递给其他的代码,其作用是在需要的时候方便调用这段(回调函数)代码。
JS中什么是回调函数?_路过的假面骑士dcd的博客
参数可以拿来用,你也可以不用。形参,形式上的参数,并没有实际意义,只是帮你完成函数内部逻辑运算而设置的。 回调函数:被作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数,称为回调函数。 functiongreeting(name){…
JS回调函数——简单易懂有实例
 初学js的时候,被回调函数搞得很晕,现在回过头来总结一下什么是回调函数。什么是JS?(点击查看) 下面先看看标准的解释: 《script language=“javascript“》 02 function SortNumber( obj, func ) // 定义通用排序函数 03 { 04 //…
继续访问
浅析JS中回调函数及用法
主要介绍了JS中回调函数及用法,通过实例代码给大家详细介绍了什么是回调函数,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧
JS回调函数(callback)
浅谈JS回调函数
继续访问
JS中的 回调函数(callback)
目录1.什么是回调函数(callback)呢?2.回调函数有哪些特点?3.回调函数中this的指向问题4.为什么要用到回调函数?5.回调函数和异步操作的关系是什么?回调函数是异步么?把函数当作一个参数传到另外一个函数中,当需要用这个函数是,再回调运行()这个函数.回调函数是一段可执行的代码段,它作为一个参数传递给其他的代码,其作用是在需要的时候方便调用这段(回调函数)代码。(作为参数传递到另外一个函数中,这个作为参数的函数就是回调函数)理解:函数可以作为一个参数传递到另外一个函数中。 分析:add(1,
继续访问
js之回调函数
回调函数 回调函数被作为实参传入另一函数,并在该外部函数内被调用,用以来完成某些任务的函数,称为回调函数。 一个简单的例子 《script type=“text/javascript“》 window.onload = function(){ // 回调函数 function a(m){ return m+m; } console.log(a(3));//6 返回一个数据 console.log(a);//f a(m){return m+n} 返
继续访问
<Zhuuu_ZZ>HIVE(十一)函数
Hive内置函数一 Hive函数分类二 字符函数二 类型转换函数和数学函数三 日期函数四 集合函数五 条件函数六 聚合函数和表生成函数6.1 聚合函数6.2 表生成函数:输出可以作为表使用 一 Hive函数分类 从输入输出角度分类 标准函数:一行数据中的一列或多列为输入,结果为单一值 聚合函数:多行的零列到多列为输入,结果为单一值 表生成函数:零个或多个输入,结果为多列或多行 从实现方式分类 内置函数 自定义函数 UDF:自定义标准函数 UDAF:自定义聚合函数 UDTF:自定义表生成函数
继续访问

常见的开窗函数
开窗函数与聚合函数计算方式一样,开窗函数也是对行集组进行聚合计算,但是它不像普通聚合函数那样每组只返回一个值,开窗函数可以为每组返回多个值。 开窗函数的语法为:over(partition by 列名1 order by 列名2 ),括号中的两个关键词partition by 和order by 可以只出现一个。over() 前面是一个函数,如果是聚合函数,那么order by 不能一起使用。 开窗函数主要分为以下两类: 窗口函数OVER()指定一组行,开窗函数计算从窗口函数输出的结果集中各行的值。
继续访问

开窗函数总结
4.2.1,表的数据 4.2.3,开窗函数查询 1,结果如下: 2,结果如下,可以参照这个结果进行理解rows和range的区别 3,结果如下,可以用于获取当前数据行的 上次登录时间 的需求 4,结果如下,结合lead()函数 可以获取用户 上次登录时间与下次登录时间的 需求 5,结果如下,可以用于指定时间内最新或最旧数据的需求。 6,结果如下,可用于求比例的需求 7,结果如下: 7,结果如下: 8,结果如下 9,结果如下: ,10,结果
继续访问

热门推荐 python中def用法
一、函数调用的含义 函数是类似于可封装的程序片段。允许你给一块语句一个名字,允许您在你的程序的任何地方使用指定的名字运行任何次数。 python中有许多内置函数,如len和range。 函数概念可能是任何有价值软件中最重要的块(在任何编程语言中)。 二、定义函数使用def关键字 在这个关键字之后是标识函数的名字; 其次是在一对括号中可以附上一些变量名; 最后在行的末尾…
继续访问
python map函数的作用_python语言基础之map函数,urlib.request,多线程
1.map函数map 是 Python 自带的内置函数,它的作用是把一个函数应用在一个(或多个)序列上,把列表中的每一项作为函数输入进行计算,再把计算的结果以列表的形式返回。map 的第一个参数是一个函数,之后的参数是序列,可以是 list、tuple。当 map 中的函数为 None 时,结果将会直接返回参数组成的列表。(python3中去掉了None,会报错)lst_1 = (1,2,3,4,…
继续访问
JS中什么是回调函数?
对于刚学JS的初学者来说(包括我现在的自己),对于这个回调函数真的是踩坑无数,于是乎想作为一个淋过雨的人,想为后面刚入门的人打一把伞。 本文不会用专业的知识词汇,只会用口语来简单让你有一个概念帮你浅浅的理解这个名词,如果你是一个学习JS刚遇到这个名词,正处于一脸懵逼的状态,那么本文对于会有帮助,但如果你想要研究更深层次的原理,用法和含义,可能本文不适合你。 废话不多说,让我们先看MDN的解释。 这段话,首先我们要搞懂一个东西,什么是实参。 我们都知道,函数可以接受参数,形参和实参。那么什么是
继续访问

js回调函数的两种写法
回调函数 应用程序时常会通过API调用库里所预先备好的函数。但是有些库函数(library function)却要求应用先传给它一个函数,好在合适的时候调用,以完成目标任务。这个被传入的、后又被调用的函数就称为回调函数(callback function)。 总结一下回调函数的两种写法与用法: 非参数回调函数: 这种回调比较简单 ,往往只需传一个函数名就可以。 function demo(arg,callback){ } 再来看看怎么写这个函数 在js中是可以通过函数名来调用函数的 例如: var
继续访问
【一句话攻略】彻底理解JS中的回调(Callback)函数
回调函数
继续访问
SQL开窗函数(窗口函数)详解
一、什么是开窗函数 开窗函数/分析函数:over() 开窗函数也叫分析函数,有两类:一类是聚合开窗函数,一类是排序开窗函数。 开窗函数的调用格式为: 函数名(列名) OVER(partition by 列名 order by列名) 。 如果你没听说过开窗函数,看到上面开窗函数的调用方法,你可能还会有些疑惑。但只要你了解聚合函数,那么理解开窗函数就非常容易了。 我们知道聚合函数对一组值执行计算并返回单一的值,如sum(),count(),max(),min(), avg()等,这些函数常与grou
继续访问
最新发布 Python中很常用的函数map(),一起来看看用法
Python2中map直接返回作用后的元素的列表 Python3中map返回的则是一个map对象 如果想得到列表对象,则还需要调用list转化为列表对象 Python2中,map()函数的 function 可以为None,如map(iterable1,iterable2[,…[,iterable n),其作用类似于将iterable*中的对应索引的值取出作为一个元组,最终返回一个包含多个元组的列表。而Python3中,不指定 function,就会报错。
继续访问

Oracle分析函数Over()
一、Over()分析函数 说明:聚合函数(如sum()、max()等)可以计算基于组的某种聚合值,但是聚合函数对于某个组只能返回一行记录。若想对于某组返回多行记录,则需要使用分析函数。 1、rank()/dense_rank over(partition by … order by …) 说明:over()在什么条件之上;   partition by 按哪个字段划分组;   …
继续访问
mysql开窗函数有哪些_mysql开窗函数
开窗函数:它可以理解为记录集合,开窗函数也就是在满足某种条件的记录集合上执行的特殊函数。对于每条记录都要在此窗口内执行函数,有的函数随着记录不同,窗口大小都是固定的,这种属于静态窗口;有的函数则相反,不同的记录对应着不同的窗口,这种动态变化的窗口叫滑动窗口。开窗函数的本质还是聚合运算,只不过它更具灵活性,它对数据的每一行,都使用与该行相关的行进行计算并返回计算结果。开窗函数和普通聚合函数的区别聚合…
继续访问
SQL:开窗函数(窗口函数)
4、 窗口函数 目录4、 窗口函数4.1 排序窗口函数rank4.2 rank(), dense_rank(), row_number()区别4.3 、排序截取数据lag(),lead(),ntile(),cume_dist()4.4 聚合函数作为窗口函数4.4、over(- – rows between and ) 简单理解,就是对查询的结果多出一列,这一列可以是聚合值,也可以是排序值。 开窗函数一般就是说的是over()函数,其窗口是由一个 OVER 子句 定义的多行记录 开窗函数一般分为两类,
继续访问

开窗函数(分析函数)使用详解
开窗函数 简介 开窗函数:在开窗函数出现之前存在着很多用 SQL 语句很难解决的问题,很多都要通过复杂的相关子查询或者存储过程来完成。为了解决这些问题,在 2003 年 ISO SQL 标准加入了开窗函数,开窗函数的使用使得这些经典的难题可以被轻松的解决。目前在 MSSQLServer、Oracle、DB2 等主流数据库中都提供了对开窗函数的支持,MySQL8.0支持。 5.7 –》 8.0 开窗函数简介:与聚合函数一样,开窗函数也是对行集组进行聚合计算,但是它不像普通聚合函数那样每组只返回一个
继续访问

敲黑板啦!开窗函数你学会了吗
特征分析与偏移分析什么是开窗函数?学习目标:1、累计计算窗口函数(1)sum(…) over(……)(2)avg(…) over(……)(3)语法总结:2、分区排序窗口函数3、分组排序窗口函数4、偏移分析窗口函数练习总结: 什么是开窗函数? 开窗函数用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回…
继续访问

Hive开窗函数

first_value:取分组内排序后,截止到当前行,第一个值;
last_value:取分组内排序后,截止到当前行,最后一个值;
lead(col, n, default):用于统计窗口内往下第n行值。第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为null时,取默认值,如不指定则为null);
lag(col, n, default):与lead相反,用于统计窗口内往上第n行值。第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往上第n行为null时,取默认值,如不指定,则为null)。

1)使用标准的聚合函数 count、sum、min、max、avg
2)使用 partition by 语句,使用一个或多个原始列
3)使用 partition by 与 order by 语句,使用一个或多个分区或者排序列
4)使用窗口规范,窗口规范支持以下格式:

当 ORDER BY 后面缺少窗口从句条件,窗口规范默认是 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW .

当 ORDER BY 和窗口从句都缺失, 窗口规范默认是 ROW BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING .

OVER 从句支持以下函数, 但是并不支持和窗口一起使用它们。
Ranking 函数: Rank, NTile, DenseRank, CumeDist, PercentRank .
Lead 和 Lag 函数.

row_number() :从1开始,按照顺序生成组内记录的序列,比如按照pv降序排列生成分组内的pv排名;获取分组内的top1记录;获取一个session内的第一条记录等等。
rank() :生成数据项在分组内的排名,排名相等会在名次中留下空位。
dense_rank() :生成数据项在分组内的排名,排名相对不会在名次中留下空位。
cume_dist :小于等于当前值的行数/分组内总行数。比如,统计小于等于当前薪资的人数占总人数的比例。
percent_rank : (分组内当前行的rank值-1)/(分组内总行数-1)。
ntile(n) :用于将分组数据按照顺序切分成n片,返回当前切片值,如果切片不均匀,默认增加第一个切片的分布。 ntile 不支持 rows between ,比如 ntile(2) over(partition by cookieied order by createtime rows between 3 preceding and current row) 。

4、测试数据集

SQL Server中的开窗函数是什么

开窗函数(OVER子句)用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行
中同时返回基础行的列和聚合列。举例来说,如果要得到一个年级所有班级所有学生的平均
分,按照传统的写法,肯定是通过AVG聚合函数来实现求平均分。由于聚合函数是以GROUP BY 查询作为操作的上下文对一组值进行聚合,GROUP BY 操作对数据进行分组后,查询
为每个组只返回一行数据,因此,我们不能同时返回基础列(班级,学生等列),而只能得
到聚合列。

开窗函数

开窗函数

需求:
既要显示聚合前的数据,又要显示聚合后的结果

rank

开窗函数:
窗口函数: 窗口 + 函数
窗口: 函数运行时计算的数据集的范围
函数:运行时的函数:
1.常用的聚合函数
2.窗口内置的函数

1.聚合函数 -》开窗

数据:

需求:
统计累计的问题,每个用户每天累计点外卖的次数

函数 over()

2.指定窗口大小

3.开窗 -内置函数
RANK
ROW_NUMBER
DENSE_RANK
NTILE
1.NTILE
需求:
把数据按照姓名进行分组 时间排序 结果数据分成 3份数

NTILE(N):
把数据平均分配到N中,如果不能平均分配,优先分配到较小的编号中。
2.rank相关的
RANK
ROW_NUMBER
DENSE_RANK

RANK:
从1开始,按照顺序,生成组内记录的编号,排序相同会重复,在名次中留下空位
ROW_NUMBER:
从1开始,按照顺序,生成组内记录的编号,序号没有重复的
DENSE_RANK:
从1开始,按照顺序,生成组内记录的编号,排序相同会重复,在名次中不留下空位
3.蹿行问题
lag 向上取第几行
lead 向下取第几行

4.取值问题
FIRST_VALUE(col):取分组后 截止到当前行 第一个值
LAST_VALUE(col):取分组后 截止到当前行 最后一个值

开窗函数案例:
1.我们有如下的用户访问数据
userId visitDate visitCount
u01 2017/1/21 5
u02 2017/1/23 6
u03 2017/1/22 8
u04 2017/1/20 3
u01 2017/1/23 6
u01 2017/2/21 8
U02 2017/1/23 6
U01 2017/2/22 4
要求使用SQL统计出每个用户的累积访问次数,如下表所示:
用户id 月份 小计 累积
u01 2017-01 11 11
u01 2017-02 12 23
u02 2017-01 12 12
u03 2017-01 8 8
u04 2017-01 3 3

每个用户的累积访问次数=》
每个用户每个月累计访问次数
维度: 用户、月
指标:次数、累计访问次数
1.etl:
2017/2/22 =》 2017-02 日期函数 ,string函数 sql里面
2017/2/22=》2017-2-22
2.
1.先求 每个月 次数
2. 1结果 =》 累计

也可以使用str_to_date
date_format(str_to_date(visitdate,’%Y/%m/%d’) ,’%Y-%m’)as month

2.有50W个京东店铺,每个顾客访客访问任何一个店铺的任何一个商品时都会产生一条访问日志,
访问日志存储的表名为Visit,访客的用户id为user_id,被访问的店铺名称为shop,数据如下:
u1 a
u2 b
u1 b
u1 a
u3 c
u4 b
u1 a
u2 c
u5 b
u4 b
u6 c
u2 c
u1 b
u2 a
u2 a
u3 a
u5 a
u5 a
u5 a
请统计:
(1)每个店铺的UV(访客数) 、pv(访问量)
维度:店铺
指标:uv =》user_id

(2)每个店铺访问次数top3的访客信息。输出店铺名称、访客id、访问次数
维度:店铺、 访客id
指标:访问次数 、访问次数的top3

uv pv :
pv =》 page 次数 不需要去重
uv =》 user 次数 需要去重
2.行转列 &&& 列转行
1.列转行

||
v
zuoshao,《王者荣耀,黑丝,看小视频》
xuanxuan,《姐姐,天天,杰伦》
mysql没有collection_list(hobby)
可以使用group_concat(hobby)

— hive
select
name,
concat_ws(“,“,collection_list(hobby)) as hobbyies
from t1
group by
name;

concat_ws
concat

2.行转列
hive爆破函数实现

mysql没有爆破函数(免费版本没有)

开窗函数是什么

开窗函数/分析函数:over()
开窗函数也叫分析函数,有两类:一类是聚合开窗函数,一类是排序开窗函数。

sql over开窗函数 和group by的区别 / 蓝讯

如果有多个聚合函数,但是分组依据不同,此时只能使用开窗函数。
而GROUP BY要求聚合函数的分组依据一致。

开窗函数和row_number()

窗口函数的引入是为了解决 想要既显示聚集前的数据,又要显示聚集后的数据。
开窗函数对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。

over() 按所有行进行分组
over(partition by xxx) 按xxx分组的所有行进行分组
over(partition by xxx order by aaa) 按xxx分组,按列aaa排序 的按到当前行(含当前行)进行分组
over前可以加聚合函数 例如sum count avg min max等
over前也可以加 first_value last_value等
windows 字句 用来制定累加的方式
rank() over等的用法

参考资料: 如果需要排序分组的话 在over 中添加想要分组或者排序的字段

为什么我们要使用开窗函数

什么时候会用到开窗函数呢?下面介绍使用场景:
表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就只能选取单个字段

返回结果

SQL Server中的开窗函数是什么

开窗函数(OVER子句)用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行
中同时返回基础行的列和聚合列。举例来说,如果要得到一个年级所有班级所有学生的平均
分,按照传统的写法,肯定是通过AVG聚合函数来实现求平均分。由于聚合函数是以GROUP BY 查询作为操作的上下文对一组值进行聚合,GROUP BY 操作对数据进行分组后,查询
为每个组只返回一行数据,因此,我们不能同时返回基础列(班级,学生等列),而只能得
到聚合列。