开窗函数

一、简单概述

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

第一大类:聚合开窗函数 -》聚合函数 OVER(选项),这里的选项可以是PARTITION BY子句,但不可以是ORDER BY子句。
第二大类:排序开窗函数-》排序函数(列)OVER(选项),这里的选项可以是ORDER BY子句,也可以是OVER (PARTITION BY 子句 ORDER BY 子句),但不可以只是PARTITION BY子句。

二、数据准备

        val sparkConf = new SparkConf().setAppName("session").setMaster("local[*]")

        val sparkSession = SparkSession.builder().config(sparkConf).getOrCreate()

        import sparkSession.implicits._
        val scoreDF = sparkSession.sparkContext.makeRDD(Array(
            ("a1", 1, 80),
            ("a2", 1, 81),
            ("a3", 2, 80),
            ("a4", 2, 83),
            ("a5", 2, 70),
            ("a6", 3, 30),
            ("a7", 4, 50),
            ("a8", 4, 80),
            ("a9", 4, 90),
            ("a10", 5, 100)
        )).toDF("name", "class", "score")
		// 创建临时表
        scoreDF.createOrReplaceTempView("score")
    }

三、聚合开窗函数

OVER 关键字表示把聚合函数当成聚合开窗函数而不是聚合函数。SQL标准允许将所有聚合函数用做聚合函数。

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

查询结果如下图所示:

+----+-----+-----+----------+
|name|class|score|name_count|
+----+-----+-----+----------+
|  a1|    1|   80|        10|
|  a2|    1|   81|        10|
|  a3|    2|   80|        10|
|  a4|    2|   83|        10|
|  a5|    2|   70|        10|
|  a6|    3|   30|        10|
|  a7|    4|   50|        10|
|  a8|    4|   80|        10|
|  a9|    4|   90|        10|
| a10|    5|  100|        10|
+----+-----+-----+----------+
sparkSession.sql("select name, class, score, sum(score) over() total_score from score").show()

查询结果如下图所示:
±—±----±----±---------+
|name|class|score|total_score|
±—±----±----±---------+
| a1| 1| 80| 744|
| a2| 1| 81| 744|
| a3| 2| 80| 744|
| a4| 2| 83| 744|
| a5| 2| 70| 744|
| a6| 3| 30| 744|
| a7| 4| 50| 744|
| a8| 4| 80| 744|
| a9| 4| 90| 744|
| a10| 5| 100| 744|
±—±----±----±---------+

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

查询结果如下图所示:
±—±----±----±---------+
|name|class|score|name_count|
±—±----±----±---------+
| a1| 1| 80| 2|
| a2| 1| 81| 2|
| a6| 3| 30| 1|
| a10| 5| 100| 1|
| a7| 4| 50| 3|
| a8| 4| 80| 3|
| a9| 4| 90| 3|
| a3| 2| 80| 3|
| a4| 2| 83| 3|
| a5| 2| 70| 3|
±—±----±----±---------+

排序开窗函数

对于排序开窗函数来讲,它支持的开窗函数分别为:ROW_NUMBER(行号)、RANK(排名)、DENSE_RANK(密集排名)和NTILE(分组排名)。

默认是升序,如需降序:order by 字段 asc

        sparkSession.sql("select name, class, score, row_number() over(order by score) rank from score").show()

查询结果如下图所示:
±—±----±----±—+
|name|class|score|rank|
±—±----±----±—+
| a6| 3| 30| 1|
| a7| 4| 50| 2|
| a5| 2| 70| 3|
| a1| 1| 80| 4|
| a3| 2| 80| 5|
| a8| 4| 80| 6|
| a2| 1| 81| 7|
| a4| 2| 83| 8|
| a9| 4| 90| 9|
| a10| 5| 100| 10|
±—±----±----±—+

        sparkSession.sql("select name, class, score, rank() over(order by score) rank from score").show()

rank出现跳跃,总数据条数等于rank最大值
查询结果如下图所示:
±—±----±----±—+
|name|class|score|rank|
±—±----±----±—+
| a6| 3| 30| 1|
| a7| 4| 50| 2|
| a5| 2| 70| 3|
| a1| 1| 80| 4|
| a3| 2| 80| 4|
| a8| 4| 80| 4|
| a2| 1| 81| 7|
| a4| 2| 83| 8|
| a9| 4| 90| 9|
| a10| 5| 100| 10|
±—±----±----±—+

        sparkSession.sql("select name, class, score, dense_rank() over(order by score) rank from score").show()

rank 不会出现跳跃,总数据条数大于等于rank的最大值
查询结果如下图所示:
±—±----±----±—+
|name|class|score|rank|
±—±----±----±—+
| a6| 3| 30| 1|
| a7| 4| 50| 2|
| a5| 2| 70| 3|
| a1| 1| 80| 4|
| a3| 2| 80| 4|
| a8| 4| 80| 4|
| a2| 1| 81| 5|
| a4| 2| 83| 6|
| a9| 4| 90| 7|
| a10| 5| 100| 8|
±—±----±----±—+

        sparkSession.sql("select name, class, score, ntile(6) over(order by score) rank from score").show()

将组数据分为设定的组数,然后组内进行排序
查询结果如下图所示:
±—±----±----±—+
|name|class|score|rank|
±—±----±----±—+
| a6| 3| 30| 1|
| a7| 4| 50| 1|
| a5| 2| 70| 2|
| a1| 1| 80| 2|
| a3| 2| 80| 3|
| a8| 4| 80| 3|
| a2| 1| 81| 4|
| a4| 2| 83| 4|
| a9| 4| 90| 5|
| a10| 5| 100| 6|
±—±----±----±—+

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值