Spark SQL中开窗函数详解

row_number()开窗函数: 其实就是给每个分组的数据,按照其排序的顺序,打上一个分组内的行号,相当于groupTopN,在实际应用中非常广泛。

+--------+-------+------+
|deptName|   name|salary|
+--------+-------+------+
|  dept-1|Michael|  3000|
|  dept-2|   Andy|  5000|
|  dept-1|   Alex|  4500|
|  dept-2| Justin|  6700|
|  dept-2| Cherry|  3400|
|  dept-1|   Jack|  5500|
|  dept-2|   Jone| 12000|
|  dept-1|   Lucy|  8000|
|  dept-2|   LiLi|  7600|
|  dept-2|   Pony|  4200|
+--------+-------+------+

需求分析:对上面数据表按照deptName分组,并按照salary降序排序,取出每个deptName组前两名。

数据源:

{"deptName":"dept-1", "name":"Michael", "salary":3000}
{"deptName":"dept-2", "name":"Andy", "salary":5000}
{"deptName":"dept-1", "name":"Alex", "salary":4500}
{"deptName":"dept-2", "name":"Justin", "salary":6700}
{"deptName":"dept-2", "name":"Cherry", "salary":3400}
{"deptName":"dept-1", "name":"Jack", "salary":5500}
{"deptName":"dept-2", "name":"Jone", "salary":12000}
{"deptName":"dept-1", "name":"Lucy", "salary":8000}
{"deptName":"dept-2", "name":"LiLi", "salary":7600}
{"deptName":"dept-2", "name":"Pony", "salary":4200}

初始化SparkSession

package com.kfk.spark.common

import org.apache.spark.sql.SparkSession

/**
 * @author : 蔡政洁
 * @email :caizhengjie888@icloud.com
 * @date : 2020/12/2
 * @time : 10:02 下午
 */
object CommSparkSessionScala {
    def getSparkSession(): SparkSession ={
        val spark = SparkSession
                .builder
                .appName("CommSparkSessionScala")
                .master("local")
                .config("spark.sql.warehouse.dir", "/Users/caizhengjie/Document/spark/spark-warehouse")
                .getOrCreate

        return spark
    }
}

实现开窗函数

package com.kfk.spark.sql

import com.kfk.spark.common.{Comm, CommSparkSessionScala}

/**
 * @author : 蔡政洁
 * @email :caizhengjie888@icloud.com
 * @date : 2020/12/8
 * @time : 12:22 下午
 */
object WindowFunctionScala {
    def main(args: Array[String]): Unit = {
        val spark = CommSparkSessionScala.getSparkSession()

        val userPath = Comm.fileDirPath + "users.json"
        spark.read.json(userPath).show()

        /**
         * +--------+-------+------+
         * |deptName|   name|salary|
         * +--------+-------+------+
         * |  dept-1|Michael|  3000|
         * |  dept-2|   Andy|  5000|
         * |  dept-1|   Alex|  4500|
         * |  dept-2| Justin|  6700|
         * |  dept-2| Cherry|  3400|
         * |  dept-1|   Jack|  5500|
         * |  dept-2|   Jone| 12000|
         * |  dept-1|   Lucy|  8000|
         * |  dept-2|   LiLi|  7600|
         * |  dept-2|   Pony|  4200|
         * +--------+-------+------+
         */

        spark.read.json(userPath).createOrReplaceTempView("user")

        // 实现开窗函数:所谓开窗函数就是分组求TopN
        spark.sql("select deptName,name,salary,rank from" +
                "(select deptName,name,salary,row_number() OVER (PARTITION BY deptName order by salary desc) rank from user) tempUser " +
                "where rank <=2").show()

        /**
         * +--------+----+------+----+
         * |deptName|name|salary|rank|
         * +--------+----+------+----+
         * |  dept-1|Lucy|  8000|   1|
         * |  dept-1|Jack|  5500|   2|
         * |  dept-2|Jone| 12000|   1|
         * |  dept-2|LiLi|  7600|   2|
         * +--------+----+------+----+
         */

        // 实现分组排序
        spark.sql("select * from user order by deptName,salary desc").show()

        /**
         * +--------+-------+------+
         * |deptName|   name|salary|
         * +--------+-------+------+
         * |  dept-1|   Lucy|  8000|
         * |  dept-1|   Jack|  5500|
         * |  dept-1|   Alex|  4500|
         * |  dept-1|Michael|  3000|
         * |  dept-2|   Jone| 12000|
         * |  dept-2|   LiLi|  7600|
         * |  dept-2| Justin|  6700|
         * |  dept-2|   Andy|  5000|
         * |  dept-2|   Pony|  4200|
         * |  dept-2| Cherry|  3400|
         * +--------+-------+------+
         */

    }
}

以上内容仅供参考学习,如有侵权请联系我删除!
如果这篇文章对您有帮助,左下角的大拇指就是对博主最大的鼓励。
您的鼓励就是博主最大的动力!

开窗函数Spark SQL是一种用于对结果集进行分析和聚合计算的功能。它可以对结果集按照指定的分区进行分组,并在每个分组进行聚合计算。开窗函数在解决一些复杂的问题时非常有用,可以简化SQL语句的编写,并提高查询效率。 Spark SQL开窗函数可以通过使用窗口规范来定义,窗口规范包括分区和排序的规则。分区规则用于将结果集划分为不同的分组,而排序规则用于在每个分组确定计算的顺序。 通过使用开窗函数,您可以在同一SELECT语句同时使用多个开窗函数,并且它们之间不会相互干扰。例如,您可以使用COUNT函数来计算每个分组的记录数,或者使用RANK函数来计算每个分组的排名。 以下是一个使用Spark SQL开窗函数的示例: ```spark sparkSession.sql("SELECT name, class, score, COUNT(name) OVER(PARTITION BY class) AS name_count1 FROM score").show() sparkSession.sql("SELECT name, class, score, COUNT(name) OVER(PARTITION BY score) AS name_count2 FROM score").show() ``` 在这个示例,第一个SELECT语句使用COUNT函数,按照班级进行分组,并计算每个班级的学生数量。第二个SELECT语句使用COUNT函数,按照分数进行分组,并计算每个分数对应的学生数量。 总之,Spark SQL开窗函数是一种强大的工具,可以帮助您对结果集进行灵活的分析和聚合计算。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Spark SQL开窗函数](https://blog.csdn.net/weixin_39966065/article/details/93099293)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Spark SQL——开窗函数](https://blog.csdn.net/weixin_44240370/article/details/103322615)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

<一蓑烟雨任平生>

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值