SparkSQL的开窗函数

1. 简介

开窗函数简介:

  • 开窗函数是为了既显示聚集前的数据,又显示聚集后的数据。即在每一行的最后一列添加聚合函数的结果。
  • 窗用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合),它对一组值进行操作,不需要使用 GROUP BY 子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列

聚合函数和开窗函数区别:

  • 聚合函数是将多行变成一行,count,avg…
  • 开窗函数是将一行变成多行
  • 聚合函数如果要显示其他的列必须将列加入到group by
  • 开窗函数可以不使用group by直接将所有信息显示出来

开窗函数分类:

1.聚合开窗函数

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

2.排序开窗函数

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

2. 聚合开窗函数

  • OVER 关键字表示把聚合函数当成聚合开窗函数而不是聚合函数。
  • 开窗函数的 OVER 关键字后括号中的可以使用 PARTITION BY 子句来定义行的分区来供进行聚合计算。

3. 排序开窗函数

  • ROW_NUMBER顺序排序 123
  • RANK 跳跃排序 1 2 4
  • DENSE_RANK 连续排序 1223

4. Spark开窗函数代码演示

import org.apache.spark.sql.{DataFrame, SparkSession}

/**
 * @author liu a fu
 * @date 2021/1/26 0026
 * @version 1.0
 * @DESC   Spark的开窗函数演示
 */
case class Score(name: String, clazz: Int, score: Int)

object _15SessionAndWindos {
  def main(args: Array[String]): Unit = {
    //1-环境准备
    val spark: SparkSession = SparkSession
      .builder()
      .appName(this.getClass.getSimpleName.stripSuffix("$"))
      .master("local[*]")
      .getOrCreate()
    spark.sparkContext.setLogLevel("WARN")

    //从rdd转化到df需要导入隐式转换
    import spark.implicits._

    //2-读取数据
    val scoreDF: DataFrame = 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()

    //1-聚合类的开窗函数
    spark.sql("select count(name) from scores").show()
    //+-----------+
    //|count(name)|
    //+-----------+
    //|         11|
    //+-----------+

    /**
     *  总的count(name)数显示出来了
     */
    spark.sql("select name,class,score,count(name) over() as 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|
     * +----+-----+-----+----------+
     */


    //每一个班的count(name)显示出来  partition by 按照班级分区
    spark.sql("select name,class,score,count(name) over(partition by class) as 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|
     * +----+-----+-----+----------+
     */

    //2-排序类开窗函数
    //row_number 123
    spark.sql("select name,class,score,row_number() over(order by score) rank from scores").show()
    spark.sql("select name,class,score,row_number() over(partition by class order by score) rank from scores").show()

    //rank 124
    spark.sql("select name,class,score,rank() over(order by score) rank from scores").show()
    spark.sql("select name,class,score,rank() over(partition by class order by score) rank from scores").show()

    //dense_rank 223
    spark.sql("select name,class,score,dense_rank() over(order by score) rank from scores").show()
    spark.sql("select name,class,score,dense_rank() over(partition by class order by score) rank from scores").show()

    spark.stop()
  }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值