Oracle—开窗函数

  在我们使用SQL语句进行查询的时候,有时候会用到分组函数对数据进行分组,求取分组之后的某个值。分组函数用于求取分组后的某个值,有时候这种查询并不能满足我们的需求,这就有了开窗函数,开窗函数也能对数据进行分组。
  开窗函数的作用是计算基于组的某种聚合值。开窗函数指定了分析函数工作的数据窗口大学,这个数据窗口大小可能会随着行的变化而变化。它与分组函数的区别在于开窗函数是对于每个组返回多行,而分组函数则是对于每个组只返回一行。
  函数写法:
  OVER(PARTITION BY ‘x’ ORDER BY ‘y’)——按照y排序进行累计,ORDER BY是个默认的开窗函数,按照x进行分区。
  开窗的窗口范围:
  OVER(ORDER BY ‘x’ RANGE BETWEEN 3 PRECEDING AND 3 FOLLOWING)——窗口范围为当前行数据幅度减3加3后的范围内的,可以看作逻辑范围。
  OVER(ORDER BY ‘x’ ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING)——窗口范围为当前行前后各移动3行,可以看作物理范围。
  代码示例:
Oracle—开窗函数_第1张图片
  上面两个开窗函数的意思:根据学生号分区,查询当前行数据的分区内总成绩,上面两个查询的开窗范围都为1。下面进行详细讲解:
  首先说逻辑范围,根据学生号为1的分区,那么它的窗口范围就是当前行数据幅度加1减1,也就是1+1,1-1, 得到的结果就是2和0,那么学生号的分区范围就是0,1,2,而数据中没有学生号为0的,所以只能取到学生号为1和2的3条数据,结果就是这三条数据的成绩总和(78+81+72=231)。依次类推,学生号为4的分区,它的窗口范围就是4加一减一,也就是3,4,5,而数据中没有学生号为3的,所以只能取到学生号为4和5的4条数据。
  然后是物理范围,这个就好理解了,还是以学生号为1的分区,那么它的窗口范围就是当前行前后各移动1行,照样学生号为1的前面没有所以不取,在取后面一行,所以结果就是第一和第二行的成绩总和(78+81=159),以此类推,学生号为4的分区(上面有两个,我们这假设为第一个),它的窗口范围就是前后各移动一行,也就是2,4,4,所以取到的是最后一个是学生号为2的和最后一个学生号为4以及它本身的3条数据。
  需要注意的是:如果有多个相同的学生号,那么开窗函数会把它们的成绩求和看作为1个,所以多个相同的学生号它们算法是用相同的学生号的成绩之和加上分区内其他不相同的成绩。
  与OVER()函数结合使用的函数,PARTITION BY(对某个值进行分区),ORDER BY(对某个值进行排序):

  • DENSE_RANK():连续排序,有两个第一名时仍然跟着第二名
    Oracle—开窗函数_第2张图片
  • RANK():跳跃排序,有两个第一名时接下来就是第三名,并且不过滤并列的数据
    Oracle—开窗函数_第3张图片
  • ROW_NUMBER():过滤并列的数据,只返回一行

Oracle—开窗函数_第4张图片

  • FIRST_VALUE():返回第一行

Oracle—开窗函数_第5张图片
  下面还有很多用法和分组函数大致相同,就不一一列举了,简单介绍一下,和上面用法类似:
count() over(partition by … order by …):求分组后的总数。
max() over(partition by … order by …):求分组后的最大值。
min() over(partition by … order by …):求分组后的最小值。
avg() over(partition by … order by …):求分组后的平均值。
lag() over(partition by … order by …):取出前n行数据。
lead() over(partition by … order by …):取出后n行数据。

你可能感兴趣的:(基础知识小结)