抖音资讯

douyinzx

sql开窗函数有哪些(sql窗口函数和开窗函数讲解)

iseeyu2年前 (2024-05-06)抖音资讯155

1.概述

介绍

相信用过MySQL的朋友都知道,MySQL中也有开窗函数的存在。开窗函数的引入是为了既显示聚集前的数据,又显示聚集后的数据。即在每一行的最后一列添加聚合函数的结果。

 

开窗用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用 GROUP BY 子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。

 

聚合函数和开窗函数

聚合函数是将多行变成一行,count,avg…

开窗函数是将一行变成多行

聚合函数如果要显示其他的列必须将列加入到group by中

开窗函数可以不使用group by,直接将所有信息显示出来

 

开窗函数分类

聚合开窗函数

聚合函数(列) OVER(选项),这里的选项可以是PARTITION BY 子句,但不可以是 ORDER BY 子句。

 

排序开窗函数

排序函数(列) OVER(选项),这里的选项可以是ORDER BY 子句,也可以是OVER(PARTITION BY 子句 ORDER BY 子句),但不可以是 PARTITION BY 子句。

 

2. 准备工作

进入到SparkShell命令行

/export/servers/spark/bin/spark-shell --master spark://node01:7077,node02:7077

创建一个样例类,用于封装数据

case class Score(name: String, clazz: Int, score: Int)

创建一个RDD数组,造一些数据,并调用toDF方法将其转换成DataFrame

val scoreDF = spark.sparkContext.makeRDD(Array(
Score("a1", 1, 80),
Score("a2", 1, 78),
Score("a3", 1, 95),
Score("a4", 2, 74),
Score("a5", 2, 92),
Score("a6", 3, 99),
Score("a7", 3, 99),
Score("a8", 3, 45),
Score("a9", 3, 55),
Score("a10", 3, 78),
Score("a11", 3, 100))
).toDF("name", "class", "score")

创建一个临时表

scoreDF.createOrReplaceTempView("scores")

查询所有数据

scoreDF.show()
+----+-----+-----+
|name|class|score|
+----+-----+-----+
| a1|    1| 80|
| a2|    1| 78|
| a3|    1| 95|
| a4|    2| 74|
| a5|    2| 92|
| a6|    3| 99|
| a7|    3| 99|
| a8|    3| 45|
| a9|    3| 55|
| a10|    3| 78|
| a11|    3| 100|
+----+-----+-----+

3. 聚合开窗函数

示例1

OVER 关键字表示把聚合函数当成聚合开窗函数而不是聚合函数。

SQL标准允许将所有聚合函数用做聚合开窗函数。

spark.sql("select  count(name)  from scores").show spark.sql("select name, class, score, count(name) over() name_count from scores").show

查询结果如下所示:

查询结果如下所示:
+----+-----+-----+----------+                                                   
|name|class|score|name_count|
+----+-----+-----+----------+
| a1|    1| 80|        11| |  a2| 1|   78| 11|
| a3|    1| 95|        11| |  a4| 2|   74| 11|
| a5|    2| 92|        11| |  a6| 3|   99| 11|
| a7|    3| 99|        11| |  a8| 3|   45| 11|
| a9|    3| 55|        11| | a10| 3|   78| 11|
| a11|    3| 100|        11| +----+-----+-----+----------+

示例2

OVER 关键字后的括号中还可以添加选项用以改变进行聚合运算的窗口范围。

如果 OVER 关键字后的括号中的选项为空,则开窗函数会对结果集中的所有行进行聚合运算。

开窗函数的 OVER 关键字后括号中的可以使用 PARTITION BY 子句来定义行的分区来供进行聚合计算。与 GROUP BY 子句不同,PARTITION BY 子句创建的分区是独立于结果集的,创建的分区只是供进行聚合计算的,而且不同的开窗函数所创建的分区也不互相影响。

 

下面的 SQL 语句用于显示按照班级分组后每组的人数:

 

OVER(PARTITION BY class)表示对结果集按照 class 进行分区,并且计算当前行所属的组的聚合计算结果。

spark.sql("select name, class, score, count(name) over(partition by class) name_count from scores").show

查询结果如下所示:

+----+-----+-----+----------+                                                   
|name|class|score|name_count|
+----+-----+-----+----------+
| a1|    1| 80|         3| |  a2| 1|   78| 3|
| a3|    1| 95|         3| |  a6| 3|   99| 6|
| a7|    3| 99|         6| |  a8| 3|   45| 6|
| a9|    3| 55|         6| | a10| 3|   78| 6|
| a11|    3| 100|         6| |  a4| 2|   74| 2|
| a5|    2| 92|         2| +----+-----+-----+----------+ 

4. 排序开窗函数

4.1 ROW_NUMBER顺序排序

row_number() over(order by score) as rownum 表示按score 升序的方式来排序,并得出排序结果的序号

 

注意:

在排序开窗函数中使用 PARTITION BY 子句需要放置在ORDER BY 子句之前。

示例1

 

spark.sql("select name, class, score, row_number() over(partition by class order by score) rank from scores").show()
+----+-----+-----+----+                                                         
|name|class|score|rank|
+----+-----+-----+----+
| a2|    1| 78|   1| |  a1| 1|   80| 2|
| a3|    1| 95|   3| |  a8| 3|   45| 1|
| a9|    3| 55|   2| | a10| 3|   78| 3|
| a6|    3| 99|   4| |  a7| 3|   99| 5|
| a11|    3| 100|   6| |  a4| 2|   74| 1|
| a5|    2| 92|   2| +----+-----+-----+----+

 

4.2 RANK跳跃排序

rank() over(order by score) as rank表示按 score升序的方式来排序,并得出排序结果的排名号。

 

这个函数求出来的排名结果可以并列(并列第一/并列第二),并列排名之后的排名将是并列的排名加上并列数

 

简单说每个人只有一种排名,然后出现两个并列第一名的情况,这时候排在两个第一名后面的人将是第三名,也就是没有了第二名,但是有两个第一名。

实例2

spark.sql("select name, class, score, rank() over(order by score) rank from scores").show()                                                     
+----+-----+-----+----+
|name|class|score|rank|
+----+-----+-----+----+
| a8|    3| 45|   1| |  a9| 3|   55| 2|
| a4|    2| 74|   3| | a10| 3|   78| 4|
| a2|    1| 78|   4| |  a1| 1|   80| 6|
| a5|    2| 92|   7| |  a3| 1|   95| 8|
| a6|    3| 99|   9| |  a7| 3|   99| 9|
| a11|    3| 100|  11| +----+-----+-----+----+ 
spark.sql("select name, class, score, rank() over(partition by class order by score) rank from scores").show()
+----+-----+-----+----+                                                         
|name|class|score|rank|
+----+-----+-----+----+
| a2|    1| 78|   1| |  a1| 1|   80| 2|
| a3|    1| 95|   3| |  a8| 3|   45| 1|
| a9|    3| 55|   2| | a10| 3|   78| 3|
| a6|    3| 99|   4| |  a7| 3|   99| 4|
| a11|    3| 100|   6| |  a4| 2|   74| 1|
| a5|    2| 92|   2| +----+-----+-----+----+

4.3 DENSE_RANK连续排序

dense_rank() over(order by score) as dense_rank 表示按score 升序的方式来排序,并得出排序结果的排名号。

 

这个函数并列排名之后的排名是并列排名加1

 

简单说每个人只有一种排名,然后出现两个并列第一名的情况,这时候排在两个第一名后面的人将是第二名,也就是两个第一名,一个第二名

 

实例3

spark.sql("select name, class, score, dense_rank() over(order by score) rank from scores").show()
+----+-----+-----+----+
|name|class|score|rank|
+----+-----+-----+----+
| a8|    3| 45|   1| |  a9| 3|   55| 2|
| a4|    2| 74|   3| |  a2| 1|   78| 4|
| a10|    3| 78|   4| |  a1| 1|   80| 5|
| a5|    2| 92|   6| |  a3| 1|   95| 7|
| a6|    3| 99|   8| |  a7| 3|   99| 8|
| a11|    3| 100|   9| +----+-----+-----+----+
spark.sql("select name, class, score, dense_rank() over(partition by class order by score) rank from scores").show()
+----+-----+-----+----+                                                         
|name|class|score|rank|
+----+-----+-----+----+
| a2|    1| 78|   1| |  a1| 1|   80| 2|
| a3|    1| 95|   3| |  a8| 3|   45| 1|
| a9|    3| 55|   2| | a10| 3|   78| 3|
| a6|    3| 99|   4| |  a7| 3|   99| 4|
| a11|    3| 100|   5| |  a4| 2|   74| 1|
| a5|    2| 92|   2| +----+-----+-----+----+

4.4 NTILE分组排名

ntile(6) over(order by score)as ntile表示按 score 升序的方式来排序,然后 6 等分成 6 个组,并显示所在组的序号。

实例4

spark.sql("select name, class, score, ntile(6) over(order by score) rank from scores").show()
+----+-----+-----+----+
|name|class|score|rank|
+----+-----+-----+----+
| a8|    3| 45|   1| |  a9| 3|   55| 1|
| a4|    2| 74|   2| |  a2| 1|   78| 2|
| a10|    3| 78|   3| |  a1| 1|   80| 3|
| a5|    2| 92|   4| |  a3| 1|   95| 4|
| a6|    3| 99|   5| |  a7| 3|   99| 5|
| a11|    3| 100|   6| +----+-----+-----+----+
spark.sql("select name, class, score, ntile(6) over(partition by class order by score) rank from scores").show()
+----+-----+-----+----+                                                         
|name|class|score|rank|
+----+-----+-----+----+
| a2|    1| 78|   1| |  a1| 1|   80| 2|
| a3|    1| 95|   3| |  a8| 3|   45| 1|
| a9|    3| 55|   2| | a10| 3|   78| 3|
| a6|    3| 99|   4| |  a7| 3|   99| 5|
| a11|    3| 100|   6| |  a4| 2|   74| 1|
| a5|    2| 92|   2| +----+-----+-----+----+

扫描二维码推送至手机访问。

版权声明:本文由西安泽虎代运营发布,如需转载请注明出处。

转载请注明出处https://www.0291.com.cn/post/43388.html

相关文章

直播代运营合同避坑:报价、KPI、违约金一次说清

直播代运营合同避坑:报价、KPI、违约金一次说清

去年西安一家女装店老板拿着合同来找我看,就一页纸,上面写着“保证月销30万”。签的时候高高兴兴,三个月后只卖了8万,代运营公司一句“市场环境不好”就撒手不管了。老板想退钱,翻出合同才发现,什么叫销售额、含不含退款、考核多久、数据以谁为准,一个字都没写。这种坑我这两年见了不止十回。 直播代运营合同看...

抖音千川投放怎么投?2026新手起量避坑指南

抖音千川投放怎么投?2026新手起量避坑指南

西安一家做本地餐饮的老张,去年底听人说抖音能拉客,先充了3000块投DOU+。一个月下来,视频播放量是上去了,团购券没卖出几张。后来他才搞清楚,DOU+是给内容加热用的,真正能把团购券卖出去的工具叫巨量千川。2026年,在抖音上做生意的商家基本绕不开这两个东西:DOU+管内容热度,千川管成交转化。...

抖音短视频带货怎么做?2026年挂车出单实操指南

抖音短视频带货怎么做?2026年挂车出单实操指南

直播带货要开播、要人设、要话术,很多西安商家试了两次就放弃了。其实还有一条更轻的路:短视频带货。拍一条视频挂上商品链接,用户刷到直接下单,不用开播,不用连麦,一个人一部手机就能跑。我见过高新一家卖手工辣条的档口,老板就拍后厨炒料,一条视频爆了,挂车链接三天卖了四千多单。我自己也帮几个西安客户跑过这...

抖音矩阵号怎么做?2026年企业多账号布局实操

抖音矩阵号怎么做?2026年企业多账号布局实操

有个西安做门窗的老板跟我抱怨,说一个号发了大半年,播放量卡在一两千上不去,问我是不是号被限流了。我让他去搜搜本地同行,人家三个号轮着发,客户搜「西安封阳台」,翻两屏全是那一家。这不是玄学,就是矩阵。说白了,矩阵不是一个号发十遍,也不是开十个号复制粘贴,而是按客户会搜什么、信什么,把账号分工排好。尤...

抖音蹭热点总翻车?2026年商家追热点的正确姿势

抖音蹭热点总翻车?2026年商家追热点的正确姿势

上周有个做建材的老板问我:热搜上那个话题全网都在拍,我是不是也该跟一条?我反问他,拍完这条视频,客户凭什么找你买瓷砖?他愣了半天没答上来。这就是大多数商家蹭热点的真实状态——看见热点就冲,拍完发现除了播放量,什么都没留下。热点不是不能蹭,是大多数人都蹭错了。我盘过自己服务的客户数据:蹭热点视频的平...

企业抖音蓝V认证2026流程:材料准备与审核避坑

企业抖音蓝V认证2026流程:材料准备与审核避坑

企业号蓝V认证,现在几乎成了西安本地商家做抖音的起手式。不管是餐饮、装修、教育还是批发档口,想挂电话、想开团购、想投DOU+,基本都绕不开这一步。这篇文章把2026年最新的蓝V认证流程、要准备的材料、审核容易挂的地方一次讲清楚。蓝V认证到底有什么用?值不值600块蓝V说白了就是抖音给企业主体做的实...

现在,非常期待与您的又一次邂逅

我们努力让每一部企业宣传片和抖音短视频成为商业大片