【问题标题】:How spark RangeBetween works with Descending Order?spark RangeBetween 如何与降序一起使用?
【发布时间】:2020-04-21 14:01:26
【问题描述】:

我认为 rangeBetween(start, end) 会查看 range(cur_value - start, cur_value + end) 的值。 https://spark.apache.org/docs/2.3.0/api/java/org/apache/spark/sql/expressions/WindowSpec.html

但是,我看到了一个示例,他们在时间戳上使用降序 orderBy(),然后将 (unboundedPreceeding, 0) 与 rangeBetween 一起使用。这使我探索了以下示例:

dd = spark.createDataFrame(
    [(1, "a"), (3, "a"), (3, "a"), (1, "b"), (2, "b"), (3, "b")],
    ['id', 'category']
)
dd.show()

# output
+---+--------+
| id|category|
+---+--------+
|  1|       a|
|  3|       a|
|  3|       a|
|  1|       b|
|  2|       b|
|  3|       b|
+---+--------+

它似乎包括了值高1的前一行。

byCategoryOrderedById = Window.partitionBy('category')\
                              .orderBy(desc('id'))\
                              .rangeBetween(-1, Window.currentRow)
dd.withColumn("sum", Fsum('id').over(byCategoryOrderedById)).show()

# output
+---+--------+---+
| id|category|sum|
+---+--------+---+
|  3|       b|  3|
|  2|       b|  5|
|  1|       b|  3|
|  3|       a|  6|
|  3|       a|  6|
|  1|       a|  1|
+---+--------+---+

并且将 start 设置为 -2,它包括大于 2 的值,但在前面的行中。

byCategoryOrderedById = Window.partitionBy('category')\
                        .orderBy(desc('id'))\
                        .rangeBetween(-2,Window.currentRow)
dd.withColumn("sum", Fsum('id').over(byCategoryOrderedById)).show()

# output
+---+--------+---+
| id|category|sum|
+---+--------+---+
|  3|       b|  3|
|  2|       b|  5|
|  1|       b|  6|
|  3|       a|  6|
|  3|       a|  6|
|  1|       a|  7|
+---+--------+---+

那么,rangeBetween 与 desc orderBy 的确切行为是什么?

【问题讨论】:

    标签: apache-spark pyspark apache-spark-sql pyspark-sql


    【解决方案1】:

    没有很好的记录,但是当使用范围(或基于值的)框架时,升序和降序会影响框架中包含的值的确定。

    让我们以您提供的示例为例:

    RANGE BETWEEN 1 PRECEDING AND CURRENT ROW
    

    根据方向的顺序,1 PRECEDING 表示:

    • current_row_value - 如果是 ASC,则为 1
    • current_row_value + 1 如果 DESC

    考虑分区b中值为1的行。

    • 按降序排列,框架包括:

      (current_value and all preceding values where x = current_value + 1) = (1, 2)

    • 按升序排列,框架包括:

      (current_value and all preceding values where x = current_value - 1) = (1)

    PS: 使用 rangeBetween(-1, Window.currentRow) 和 desc 排序就等同于 rangeBetween(Window.currentRow, 1) 和 asc 排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-01
      • 1970-01-01
      • 2022-07-30
      • 1970-01-01
      • 1970-01-01
      • 2019-10-10
      • 2015-08-03
      • 2020-04-18
      相关资源
      最近更新 更多