开窗函数和聚合函数区别:
聚合函数会对一组值进行计算并返回一个值,常见的比如sum(),count(),max(),min(), avg(),会与group by一起使用。
注意其中只有count不忽略null值,COUNT(a):返回非空值的数量。COUNT(*):返回所有行的数量(不区分空值)。
count(0)=1
ROW_NUMBER()
有些场景比如求各个班或各个学科的前几名,这时候需要每一组返回多个值,就需要开窗函数解决。
比如现在有一部分学生成绩,来自不同的班级:
求所有人中的前几名学生:
首先想到 这是对分数倒序排序,如果想只要前几名名,需要生成一个序号,所以使用ROW_NUMBER()。不分组
如果对于班级分组加上
RANK() DENSE_RANK()
进一步,如果只要第一名,或者最后一名就不能用row_number(),因为如果同班有两个并列第一,mm=1就只返回一个结果。使用RANK()
查询每个班的第一名的成绩:
RANK()在处理相同值时序号一样,但是会占位,排名可能是:12225
DENSE_RANK()在处理相同值时序号一样,但是不会占位,数字连续出现:12223
NTILE()
NTILE函数是用来将数据切割成指定数量的桶(buckets),并将每个数据行分配到对应的桶中。它可用于将数据划分为相等的小切片,为每一行分配该小切片的数字序号。
NTILE不支持ROWS BETWEEN,比如
搬运一些例子便于理解:
对于第三个例子:
NTILE(3) OVER(PARTITION BY dept_no ORDER BY salary)是根据dept_no列进行分组,意味着每个部门的数据会独立进行切割成3份。数据在每个分组内根据salary排序,然后再将排序后的数据切割成3份,并且每份数据的大小相对均匀。
————————————————
参考自:窗口函数之ntile()函数讲解https://blog.csdn.net/godlovedaniel/article/details/116571187
select ROW_NUMBER()over(order by name) as 排序,* from temp
— 排序,即使值一样,也不会重复排序。例如1,2,3,4,5
select RANK()over(order by name) as 排序,* from temp
— 排序,值一样,就重复排序,有间隙。例如1,1,3,4
select DENSE_RANK()over(order by name) as 排序,* from temp
— 排序,值一样,就重复排序,没有间隙。例如1,1,2,2,3,4,5
select NTILE(2)over(order by name) as 排序,* from temp
— 排序,分成2组。此函数一般用于取表中前百分之几的数据。例如,取数据的前25%就将数据分4组,然后字段的条件是等于1。