ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

rowsBetween + over窗口函数实际应用

2021-07-05 21:01:24  阅读:171  来源: 互联网

标签:02 03 06 04 over 2019 窗口 spark rowsBetween


over窗口函数的应用参见我上一篇博客:https://www.cnblogs.com/wanpi/p/14969000.html

rows between函数:

  • SQL语句中的rows between unbounded preceding and unbounded following ,其中:
  • unbounded preceding:表示Long.MIN_VALUE,也就是可视当前行之前的所有数据
  • unbounded following:表示Long.MAX_VALUE,也就是可视当前行之后的所有数据
  • current row:表示当前行,也就是0

下面是几个案例,帮助理解

需求1

A表里面有三条记录,字段是

ID start_time end_time

2018-02-03 2019-02-03

2019-02-04 2020-03-04

2018-08-04 2019-03-04

根据已知的三条记录用SQL写出结果为:

2018-02-03 2018-08-04

2018-08-04 2019-02-03

2019-02-03 2019-02-04

2019-02-04 2019-03-04

2019-03-04 2020-03-04

解决思路

1.拆解时间数据

2.升序排列日期

3.窗口函数

代码

package method

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.expressions.Window

object OnWindowFunction3 {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().appName("windowfunction").master("local[*]").getOrCreate()
    val rdd = spark.sparkContext.makeRDD(List(

      (1,"2018-02-03","2019-02-03"),
      (2,"2019-02-04","2020-03-04"),
      (3,"2018-08-04","2019-03-04")

    ))

    import spark.implicits._
    val df = rdd.flatMap(t3 => {
      Array(t3._2,t3._3)
    }).toDF("value")
    import org.apache.spark.sql.functions._

    val w1 = Window
      .orderBy($"value" asc)
      .rowsBetween(0,1)
    df
      .withColumn("end_time",max("value") over(w1))
      .show()
    spark.stop()
  }
}

//结果
+----------+----------+
|     value|  end_time|
+----------+----------+
|2018-02-03|2018-08-04|
|2018-08-04|2019-02-03|
|2019-02-03|2019-02-04|
|2019-02-04|2019-03-04|
|2019-03-04|2020-03-04|
|2020-03-04|2020-03-04|
+----------+----------+

需求2

统计网站访问时长。每个用户访问总时长

数据集

findsiteduration.csv

uid,date,dur
111,2019-06-20,1
111,2019-06-21,2
111,2019-06-22,3
222,2019-06-20,4
222,2019-06-21,5
222,2019-06-22,6
333,2019-06-20,7
333,2019-06-21,8
333,2019-06-22,9
444,2019-06-23,10

代码

package sparksql

import org.apache.spark.sql.SparkSession
object FindSiteDuration {
  def main(args: Array[String]): Unit = {
    val spark = SparkSession.builder().appName("test").master("local[*]").getOrCreate()
    val df = spark.read.option("header",true).csv(".\\resources\\findsiteduration.csv")

    df.createTempView("temp1")

    spark
      .sql(
        """
          |select uid,date,dur,
          |sum(dur) over(partition by uid order by date) as totaldur
          |from temp1
          |""".stripMargin).show()
    spark.stop()
  }
}

//结果
+---+----------+---+--------+
|uid|      date|dur|totaldur|
+---+----------+---+--------+
|111|2019-06-20|  1|     1.0|
|111|2019-06-21|  2|     3.0|
|111|2019-06-22|  3|     6.0|
|444|2019-06-23| 10|    10.0|
|222|2019-06-20|  4|     4.0|
|222|2019-06-21|  5|     9.0|
|222|2019-06-22|  6|    15.0|
|333|2019-06-20|  7|     7.0|
|333|2019-06-21|  8|    15.0|
|333|2019-06-22|  9|    24.0|
+---+----------+---+--------+

//每个用户访问当天和前一天两天访问时长
    spark
      .sql(
        """
         |select uid,date,dur,
          |sum(dur) over(partition by uid order by date rows between 1 preceding and current row) as totaldur
          |from temp1
          |""".stripMargin).show()

//结果
+---+----------+---+--------+
|uid|      date|dur|totaldur|
+---+----------+---+--------+
|111|2019-06-20|  1|     1.0|
|111|2019-06-21|  2|     3.0|
|111|2019-06-22|  3|     5.0|
|444|2019-06-23| 10|    10.0|
|222|2019-06-20|  4|     4.0|
|222|2019-06-21|  5|     9.0|
|222|2019-06-22|  6|    11.0|
|333|2019-06-20|  7|     7.0|
|333|2019-06-21|  8|    15.0|
|333|2019-06-22|  9|    17.0|
+---+----------+---+--------+

//每个用户当天和前一天,后一天三天的网站访问时长

spark
      .sql(
        """
          |select uid,date,dur,
          |sum(dur) over(partition by uid order by date rows between 1 preceding and 1 following) as totaldur
          |from temp1
          |""".stripMargin).show()

//结果
+---+----------+---+--------+
|uid|      date|dur|totaldur|
+---+----------+---+--------+
|111|2019-06-20|  1|     3.0|
|111|2019-06-21|  2|     6.0|
|111|2019-06-22|  3|     5.0|
|444|2019-06-23| 10|    10.0|
|222|2019-06-20|  4|     9.0|
|222|2019-06-21|  5|    15.0|
|222|2019-06-22|  6|    11.0|
|333|2019-06-20|  7|    15.0|
|333|2019-06-21|  8|    24.0|
|333|2019-06-22|  9|    17.0|
+---+----------+---+--------+

标签:02,03,06,04,over,2019,窗口,spark,rowsBetween
来源: https://www.cnblogs.com/wanpi/p/14974341.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有