spark RangeBetween 如何与降序一起使用?
How spark RangeBetween works with Descending Order?
我认为 rangeBetween(start, end) 会查看范围的值(cur_value - 开始,cur_value + 结束)。 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|
+---+--------+---+
并且开始设置为 -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 的确切行为是什么?
没有很好的记录,但是当使用范围(或基于值)框架时,升序和降序会影响框架中包含的值的确定。
让我们以您提供的示例为例:
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 排序。
我认为 rangeBetween(start, end) 会查看范围的值(cur_value - 开始,cur_value + 结束)。 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|
+---+--------+---+
并且开始设置为 -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 的确切行为是什么?
没有很好的记录,但是当使用范围(或基于值)框架时,升序和降序会影响框架中包含的值的确定。
让我们以您提供的示例为例:
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 排序。