2019独角兽企业重金招聘Python工程师标准>>>

databricks博客给出的窗口函数概述

Spark SQL supports three kinds of window functions: ranking functions, analytic functions, and aggregate functions. The available ranking functions and analytic functions are summarized in the table below. For aggregate functions, users can use any existing aggregate function as a window function.

窗口函数包含3种:

  1. ranking 排名类
  2. analytic 分析类
  3. aggregate 聚合类

ranking 和 analytic 见下表,所有已经存在的聚合类函数(sum、avg、max、min)都可以作为窗口函数。

|Function Type| SQL| DataFrame API| |--|--|--| |Ranking |rank | rank | |Ranking |dense_rank|denseRank| |Ranking |percent_rank |percentRank| |Ranking |ntile|ntile| |Ranking |row_number|rowNumber| |Analytic |cume_dist|cumeDist| |Analytic |first_value |firstValue| |Analytic |last_value |lastValue| |Analytic |lag|lag| |Analytic |lead|lead|

先用案例说明

案例数据:/root/score.json/score.json,学生名字、课程、分数

{"name":"A","lesson":"Math","score":100}
{"name":"B","lesson":"Math","score":100}
{"name":"C","lesson":"Math","score":99}
{"name":"D","lesson":"Math","score":98}
{"name":"A","lesson":"E","score":100}
{"name":"B","lesson":"E","score":99}
{"name":"C","lesson":"E","score":99}
{"name":"D","lesson":"E","score":98}
./spark-shell --master local #本地启动spark-shell
import org.apache.spark.sql.expressions.Windowimport org.apache.spark.sql.functions._import org.apache.spark.sql.hive.HiveContextsc.setLogLevel("WARN") // 日志级别,可不改val hiveContext = new HiveContext(sc)val df = hiveContext.read.json("file:///root/score.json")case class Score(val name: String, val lesson: String, val score: Int)df.registerTempTable("score") // 注册临时表// SQL语句val stat = "select".concat(" name,lesson,score, ").concat(" ntile(2) over (partition by lesson order by score desc ) as ntile_2,").concat(" ntile(3) over (partition by lesson order by score desc ) as ntile_3,").concat(" row_number() over (partition by lesson order by score desc ) as row_number,").concat(" rank() over (partition by lesson order by score desc ) as rank, ").concat(" dense_rank() over (partition by lesson order by score desc ) as dense_rank, ").concat(" percent_rank() over (partition by lesson order by score desc ) as percent_rank ").concat(" from score ").concat(" order by lesson,name,score")hiveContext.sql(stat).show // 执行语句得到的结果/*** 用DataFrame API的方式完成相同的功能。
**/val window_spec = Window.partitionBy("lesson").orderBy(df("score").desc) // 窗口函数中公用的子句df.select(df("name"), df("lesson"), df("score"),ntile(2).over(window_spec).as("ntile_2"),ntile(3).over(window_spec).as("ntile_3"),row_number().over(window_spec).as("row_number"),rank().over(window_spec).as("rank"),dense_rank().over(window_spec).as("dense_rank"),percent_rank().over(window_spec).as("percent_rank")).orderBy("lesson", "name", "score").show
  • 输出结果完全一样,如下表所示
name lesson score ntile_2 ntile_3 row_number rank dense_rank percent_rank
A E 100 1 1 1 1 1 0.0
B E 99 1 1 2 2 2 0.3333333333333333
C E 99 2 2 3 2 2 0.3333333333333333
D E 98 2 3 4 4 3 1.0
A Math 100 1 1 1 1 1 0.0
B Math 100 1 1 2 1 1 0.0
C Math 99 2 2 3 3 2 0.6666666666666666
D Math 98 2 3 4 4 3 1.0
  • rank遇到相同的数据则rank并列,因此rank值可能是不连续的
  • dense_rank遇到相同的数据则rank并列,但是rank值一定是连续的
  • row_number 很单纯的行号,类似excel的行号,不会因为数据相同而rank的值重复或者有间隔
  • percent_rank = 相同的分组中 (rank -1) / ( count(score) - 1 )
  • ntile(n) 是将同一组数据 循环的往n个 桶中放,返回对应的桶的index,index从1开始。
  • 结合官方博客的python调用dataframe API的写法可知,scala的写法几乎和python的一样。官方博客的地址见最下面的参考。

上面的案例,每个分组中所有的数据都参与到窗口函数中计算了。考虑下面一种场景:

  1. 各科成绩 与 该科成绩的 最高分、最高分、平均分相差多少。每一行与此行所属分组聚合后的值再做计算。参与窗口计算的数据是绝对的,就是此行所属的窗口内的所有数据。
  2. 各科成绩按从高到低排序后,比前一名相差多少。每一行与此行的前一行的值相关。参与窗口计算的数据是相对于当前行的。
  // 各科成绩和最高分、最高分、平均分差多少分// 各科成绩按从高到低排序后,比前一名差多少分val window_clause = Window.partitionBy(df("lesson")).orderBy(df("score").desc)val window_spec2 = window_clause.rangeBetween(-Int.MaxValue, Int.MaxValue) // 绝对范围val window_spec3 = window_clause.rowsBetween(-1, 0) // 相对范围,-1:当前行的前一行,df.select(df("name"),df("lesson"),df("score"),// 窗口内的第一行的score-当前的行score(df("score") - first("score").over(window_spec3)).as("score-last_score"), // 各科成绩和最高分、最高分、平均分差多少分(min(df("score")).over(window_spec2)).as("min_score"),(df("score") - min(df("score")).over(window_spec2)).as("score-min"),(max(df("score")).over(window_spec2)).as("max_score"),(df("score") - max(df("score")).over(window_spec2)).as("score-max"),(avg(df("score")).over(window_spec2)).as("avg_score"),(df("score") - avg(df("score")).over(window_spec2)).as("score-avg")).orderBy("lesson", "name", "score").show
name lesson score score-last_score min_score score-min max_score score-max avg_score score-avg
A E 100 0 98 2 100 0 99.0 1.0
B E 99 -1 98 1 100 -1 99.0 0.0
C E 99 0 98 1 100 -1 99.0 0.0
D E 98 -1 98 0 100 -2 99.0 -1.0
A Math 100 0 98 2 100 0 99.25 0.75
B Math 100 0 98 2 100 0 99.25 0.75
C Math 99 -1 98 1 100 -1 99.25 -0.25
D Math 98 -1 98 0 100 -2 99.25 -1.25

未完待续

  • Analytic functions类型的解析
  • 源码解析

参考:

  1. percent_rank
  2. databricks博客

转载于:https://my.oschina.net/corleone/blog/755393

spark sql中的窗口函数相关推荐

  1. Spark SQL中出现 CROSS JOIN 问题解决

    Spark SQL中出现 CROSS JOIN 问题解决 参考文章: (1)Spark SQL中出现 CROSS JOIN 问题解决 (2)https://www.cnblogs.com/yjd_hy ...

  2. Spark SQL 中UDF的讲解

    Spark SQL 中UDF的讲解 User Define Function, 用户自定义函数,简称UDF,存在与很多组件中. 在使用Sparksql的人都遇到了Sparksql所支持的函数太少了的难 ...

  3. Spark SQL中的DataFrame

    在2014年7月1日的 Spark Summit 上,Databricks 宣布终止对 Shark 的开发,将重点放到 Spark SQL 上.在会议上,Databricks 表示,Shark 更多是 ...

  4. 解决数据倾斜一:RDD执行reduceByKey或则Spark SQL中使用group by语句导致的数据倾斜

    一:概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的 ...

  5. SQL 中的窗口函数

    SQL 中的窗口函数(Window Functions)是一种特殊的函数,它可以在查询结果的某个区间内执行计算,而不仅仅是对单个行进行计算. 以下是一些常用的窗口函数: 1.ROW_NUMBER() ...

  6. Spark SQL中 RDD 转换到 DataFrame (方法二)

    强调它与方法一的区别:当DataFrame的数据结构不能够被提前定义.例如:(1)记录结构已经被编码成字符串 (2) 结构在文本文件中,可能需要为不同场景分别设计属性等以上情况出现适用于以下方法.1. ...

  7. 如何查询spark版本_掌握Spark SQL中的查询执行

    了解您的查询计划 自从Spark 2.x以来,由于SQL和声明性DataFrame API,在Spark中查询数据已成为一种奢侈. 仅使用几行高级代码就可以表达非常复杂的逻辑并执行复杂的转换. API ...

  8. spark sql中的first函数在多个字段使用实例

    1.建立hive表如下: CREATE EXTERNAL TABLE `newsapp.test_first`(`userkey` string, `publish_id` string, `data ...

  9. Spark SQL中StructField和StructType

    每一天都会进行更新,一起冲击未来 StructField和StructType StructType---定义数据框的结构 StructType定义DataFrame的结构,是StructField对 ...

最新文章

  1. 唱好铁血丹心谐音正规_孩子想学唱歌?儿童声乐怎么学才好?
  2. mPaas 厂商 push 不通排查指南
  3. 一直在构建版本_构建系统与代码结构SpringBoot
  4. asp.net尚未在web服务器上注册_最新版Web服务器项目详解 00 项目概述
  5. JS 前端排序 数组指定项移动到最后
  6. 【对讲机的那点事】解读无管局《回答》:充分理解物联网产业诉求,值得点赞!...
  7. 【后缀数组】洛谷P3809模板题
  8. aspx转为html5,保存ASPX 生成的html代码
  9. 新版网易云课堂视频真实地址分析
  10. 计数显示器c语言程序,单片机计数显示器.doc
  11. Kubernetes快速入门
  12. 没去Google I/O 2018大会?这里有你想知道的一切…
  13. 创建图片外链——“极简图床”
  14. “双11”购物狂欢节,所有女生走进了谁的直播间?
  15. PHP自学笔记 | phpmyadmin无法访问——开放888端口
  16. 微信小游戏设置游戏路径以及成员添加
  17. 华龙进城 一家河北农村草根起家的企业发展史(图)
  18. FPGA/IC笔试面试(一):异步FIFO最小深度计算
  19. 【永恒之塔私服今天开放了】
  20. 等级保护2.0达标要求及变化

热门文章

  1. 快速傅里叶变换_计算物理基础:第八章-快速傅里叶变换(FFT)
  2. mybatis update返回值_mybatis 详解(六)通过mapper接口加载映射文件
  3. ajax代码编程题,关于AJAX管家代码的几个基本问​​题
  4. matlab引擎函数,Matlab引擎库函数
  5. html水平分隔线样式,CSS生成漂亮的水平分隔线(horizontal rule)设计效果
  6. php 数组的格式,PHP文件格式数组
  7. c语言尖括号 注释,关于C语言include尖括号和双引号的对话
  8. es if语法 script_熬夜7天,我总结了JavaScript与ES的25个重要知识点!
  9. mysql实际项目中使用多长时间_存储过程在实际项目中用的多吗?
  10. VUE data传值