版权声明:未经同意,不得转载。 https://blog.csdn.net/qq_36235275/article/details/82502128
over()开窗函数
-
在使用聚合函数后,会将多行变成一行,而开窗函数是将一行变成多行;
-
并且在使用聚合函数后,如果要显示其他的列必须将列加入到group by中,而使用开窗函数后,可以不使用group by,直接将所有信息显示出来。
-
开窗函数适用于在每一行的最后一列添加聚合函数的结果。
开窗函数作用
-
为每条数据显示聚合信息.(聚合函数() over())
-
为每条数据提供分组的聚合函数结果(聚合函数() over(partition by 字段) as 别名)
--按照字段分组,分组后进行计算 -
与排名函数一起使用(row number() over(order by 字段) as 别名)
常用分析函数:(最常用的应该是1.2.3 的排序)
-
row_number() over(partition by ... order by ...)
-
rank() over(partition by ... order by ...)
-
dense_rank() over(partition by ... order by ...)
-
count() over(partition by ... order by ...)
-
max() over(partition by ... order by ...)
-
min() over(partition by ... order by ...)
-
sum() over(partition by ... order by ...)
-
avg() over(partition by ... order by ...)
-
first_value() over(partition by ... order by ...)
-
last_value() over(partition by ... order by ...)
-
lag() over(partition by ... order by ...)
-
lead() over(partition by ... order by ...)
lag 和lead 可以获取结果集中,按一定排序所排列的当前行的上下相邻若干offset 的某个行的某个列(不用结果集的自关联);
lag ,lead 分别是向前,向后;
lag 和lead 有三个参数,第一个参数是列名,第二个参数是偏移的offset,第三个参数是超出记录窗口时的默认值
简单的开窗函数范例:
package com.jiangnan.spark
import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession
/**
* 姓名 班级 分数
* 101 1 90
* 120 1 88
*/
case class Score(name:String,clazz:Int,score: Int)
object OpenFunction extends App {
val conf = new SparkConf().setAppName("").setMaster("local[2]")
val spark = SparkSession.builder().config(conf).getOrCreate()
import spark.implicits._
//生产数据
val score = spark.sparkContext.makeRDD(List(
Score("1001",1,90),
Score("1002",2,95),
Score("1003",3,90),
Score("1004",1,92),
Score("1005",1,88),
Score("1005",2,66),
Score("1005",3,90),
Score("1005",1,93),
Score("1005",3,99),
Score("1005",2,90),
Score("1005",2,92),
Score("1005",3,90)
)).toDF("name","clazz","score")
println("---------原始数据----------")
score.show()
println("---------求每个班级最高成绩的学生---原始做法------")
//创建一个表
score.createOrReplaceTempView("score")
println("-----------分组后求出每个班最高分数表结构----------")
spark.sql("select clazz,max(score) max from score group by clazz").show()
println("-----------原始做法,最终结果--------------")
spark.sql("select a.name,b.clazz,b.max from score a,(select clazz,max(score) max from score group by clazz) b where a.score = b.max").show()
println("------------使用开窗函数后的运算过程-------------")
spark.sql("select name,clazz,score,rank() over(partition by clazz order by score desc) rank from score").show()
println("------------使用开窗函数后最终结果-------------")
spark.sql("select * from (select name,clazz,score,rank() over(partition by clazz order by score desc) rank from score) r where r.rank = 1").show()
spark.stop()