【问题标题】:Spark Scala : Getting Cumulative Sum (Running Total) Using Analytical FunctionsSpark Scala:使用分析函数获取累积和(运行总计)
【发布时间】:2018-07-14 09:43:18
【问题描述】:

我正在使用窗口函数在 Spark 中实现累积和。 但是在应用窗口分区函数时不保持记录输入的顺序

输入数据:

val base = List(List("10", "MILLER", "1300", "2017-11-03"), List("10", "Clark", "2450", "2017-12-9"), List("10", "King", "5000", "2018-01-28"),
  List("30", "James", "950", "2017-10-18"), List("30", "Martin", "1250", "2017-11-21"), List("30", "Ward", "1250", "2018-02-05"))
  .map(row => (row(0), row(1), row(2), row(3)))

val DS1 = base.toDF("dept_no", "emp_name", "sal", "date")
DS1.show()
+-------+--------+----+----------+
|dept_no|emp_name| sal|      date|
+-------+--------+----+----------+
|     10|  MILLER|1300|2017-11-03|
|     10|   Clark|2450| 2017-12-9|
|     10|    King|5000|2018-01-28|
|     30|   James| 950|2017-10-18|
|     30|  Martin|1250|2017-11-21|
|     30|    Ward|1250|2018-02-05|
+-------+--------+----+----------+

预期输出:

+-------+--------+----+----------+-----------+
|dept_no|emp_name| sal|      date|Dept_CumSal|
+-------+--------+----+----------+-----------+
|     10|  MILLER|1300|2017-11-03|     1300.0|
|     10|   Clark|2450| 2017-12-9|     3750.0|
|     10|    King|5000|2018-01-28|     8750.0|
|     30|   James| 950|2017-10-18|      950.0|
|     30|  Martin|1250|2017-11-21|     2200.0|
|     30|    Ward|1250|2018-02-05|     3450.0|
+-------+--------+----+----------+-----------+

我试过下面的逻辑

val baseDepCumSal = DS1.withColumn("Dept_CumSal", sum("sal").over(Window.partitionBy("dept_no").
  orderBy(col("sal"), col("emp_name"), col("date").asc).
  rowsBetween(Long.MinValue, 0)
))

baseDepCumSal.orderBy("dept_no", "date").show
+-------+--------+----+----------+-----------+
|dept_no|emp_name| sal|      date|Dept_CumSal|
+-------+--------+----+----------+-----------+
|     10|  MILLER|1300|2017-11-03|     1300.0|
|     10|   Clark|2450| 2017-12-9|     3750.0|
|     10|    King|5000|2018-01-28|     8750.0|
|     30|   James| 950|2017-10-18|     3450.0|
|     30|  Martin|1250|2017-11-21|     1250.0|
|     30|    Ward|1250|2018-02-05|     2500.0|
+-------+--------+----+----------+-----------+

对于 dept_no=10,记录按预期顺序计算,而对于 dept_no=30,记录未按输入顺序计算。

【问题讨论】:

    标签: sql scala apache-spark apache-spark-sql window-functions


    【解决方案1】:

    发生这种情况是因为类型不正确。因为薪水是string

    DS1.printSchema
    root
     |-- dept_no: string (nullable = true)
     |-- emp_name: string (nullable = true)
     |-- sal: string (nullable = true)
     |-- date: string (nullable = true)
    

    它是按字典顺序排序的:

    DS1.orderBy("sal").show
    +-------+--------+----+----------+
    |dept_no|emp_name| sal|      date|
    +-------+--------+----+----------+
    |     30|  Martin|1250|2017-11-21|
    |     30|    Ward|1250|2018-02-05|
    |     10|  MILLER|1300|2017-11-03|
    |     10|   Clark|2450| 2017-12-9|
    |     10|    King|5000|2018-01-28|
    |     30|   James| 950|2017-10-18|
    +-------+--------+----+----------+ 
    

    为了得到想要的结果,你必须强制转换(并且不需要框架定义):

    DS1.withColumn("Dept_CumSal", sum("sal").over(
      Window
         .partitionBy("dept_no")
        .orderBy(col("sal").cast("integer"), col("emp_name"), col("date").asc))).show
    +-------+--------+----+----------+-----------+                                  
    |dept_no|emp_name| sal|      date|Dept_CumSal|
    +-------+--------+----+----------+-----------+
    |     30|   James| 950|2017-10-18|      950.0|
    |     30|  Martin|1250|2017-11-21|     2200.0|
    |     30|    Ward|1250|2018-02-05|     3450.0|
    |     10|  MILLER|1300|2017-11-03|     1300.0|
    |     10|   Clark|2450| 2017-12-9|     3750.0|
    |     10|    King|5000|2018-01-28|     8750.0|
    +-------+--------+----+----------+-----------+
    

    【讨论】:

      【解决方案2】:

      请注意,您的窗口(col("sal"), col("emp_name"), col("date").asc) 内的顺序与显示"dept_no", "date" 的顺序不同 为什么窗口中需要“sal”和“emp_name”?为什么不按日期订购?

      【讨论】:

        【解决方案3】:

        orderBy baseDepCumSal.orderBy("dept_no", "date").show() 中可能缺少 emp_name

        【讨论】:

          猜你喜欢
          • 2020-01-26
          • 2018-10-27
          • 2019-07-15
          • 1970-01-01
          • 1970-01-01
          • 2016-05-11
          • 2010-11-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多