SQL 的window开窗函数简单使用

18 篇文章 0 订阅
10 篇文章 0 订阅

背景:

开窗函数不论是spark的还是clickhouse的在日常的查询中是一个很常用的功能,特别是他想要解决的问题和group by的很类似,这两种容易引起混淆,本文就简单的描述下开窗函数的简单用法

使用详解

首先窗口函数和group by是完全没有交集的,他们完全没有任何关系,group by聚合数据后会导致行数合并减少,但是窗口函数不会新增行,也不会减少行,这也就意味着对于每一行,窗口函数只是附加了新的一列数据,意识到这一点很重要

其次窗口函数的执行计划就是在每条sql的最后,仅仅只是在最终的order by之前执行,所以也就意味着他不会改变最终结果的行数,仅仅是追加新的一列数据
在这里插入图片描述

我们来看看具体的用法:

 window_function (expression) OVER (
   [ PARTITION BY part_list ]
   [ ORDER BY order_list ]
   [ { ROWS | RANGE } BETWEEN frame_start AND frame_end ] )

window函数主要包括以下几类:
聚合函数:AVG(), COUNT(), MIN(), MAX(), SUM()

分析函数:FIRST_VALUE(), LAST_VALUE(), LEAD(), LAG()

排序函数:RANK(), DENSE_RANK(), ROW_NUMBER()

ROWS关键字是选择当前行的前后几行,例如 ROWS BETWEEN 5 PRECEDING AND 3 FOLLOWING 表示往前 5 行到往后 3 行,一共 9 行数据,注意这只是选择行数据作为窗口函数应用的范围,比如这9行数据应用Min函数,对于每一条记录来说应用窗口函数后只会得到一个结果,比如这里的最小值,我们以获取一个每个学生最高的top2学科作为例子,假设每个学生都参与五门考试,记录学生成绩的表如下

create table student{

 stu_no  String,

course  String

 score  int

}

我们想要获取每个学生最高的两门学科的成绩,我们利用开窗函数怎么得到呢?

select stu_no,course,score from 
(select stu_no,course, score,row_number() over(PARTITION BY stu_no order by score) as row_num
from student) as a
where row_num <= 2;

或者

select stu_no,course,score from 
(select stu_no,course, score,row_number() over(PARTITION BY stu_no order by score ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as row_num
from student) as a
where row_num <= 2

上面这两个sql是等价的,都可以得到每个学生分数最高的两门课程

备注: 窗口函数和group by想要解决的问题具有相似性,不过从用法角度来看,这两者没有任何交集,窗口函数会作用于group by的最终结果之上,也就是在select 之后,在最终返回结果之前

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值