运行以下代码:
val sales = Seq( (0, 0, 0, 5), (1, 0, 1, 3), (2, 0, 2, 1), (3, 1, 0, 2), (4, 2, 0, 8), (5, 2, 2, 8)) .toDF("id", "orderID", "prodID", "orderQty") val orderedByID = Window.orderBy('id) val totalQty = sum('orderQty).over(orderedByID).as('running_total) val salesTotalQty = sales.select('*, totalQty).orderBy('id) salesTotalQty.show
结果是:
+---+-------+------+--------+-------------+ | id|orderID|prodID|orderQty|running_total| +---+-------+------+--------+-------------+ | 0| 0| 0| 5| 5| | 1| 0| 1| 3| 8| | 2| 0| 2| 1| 9| | 3| 1| 0| 2| 11| | 4| 2| 0| 8| 19| | 5| 2| 2| 8| 27| +---+-------+------+--------+-------------+
上面的代码中没有定义任何窗口框架,它看起来默认的窗口框架是 rowsBetween(Window.unboundedPreceding, Window.currentRow)
rowsBetween(Window.unboundedPreceding, Window.currentRow)
不确定我对默认窗口框架的理解是否正确
从Spark Gotchas
默认帧规格取决于给定窗口定义的其他方面: 如果指定了ORDER BY子句,并且该函数接受了帧规范,则该帧规范是由RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW定义的, 否则,帧规格由未绑定的前导和未绑定的后继之间的行定义。
默认帧规格取决于给定窗口定义的其他方面: