Spark Window 函数:是不是可以直接从使用第一个/最后一个函数找到的行中获取其他值?
Posted
技术标签:
【中文标题】Spark Window 函数:是不是可以直接从使用第一个/最后一个函数找到的行中获取其他值?【英文标题】:Spark Window functions: is it possible to get other values directly from a row found with the first/last functions?Spark Window 函数:是否可以直接从使用第一个/最后一个函数找到的行中获取其他值? 【发布时间】:2019-01-08 08:11:29 【问题描述】:在 Spark 中,可以在窗口中的列当前出现之后获取第一个非空值:
val window = Window
.orderBy("id")
val df = Seq(
(0, "Bob", Some(123)),
(1, "Jack", None),
(2, "Brian", None),
(3, "John", Some(456)),
(4, "Edgar", None)
).toDF("id", "name", "value")
df
.withColumn("firstNonNullValueAfterRow", first("value", true)
.over(window.rowsBetween(Window.currentRow, Window.unboundedFollowing)))
.show()
输出:
+---+-----+-----+-------------------------+
| id| name|value|firstNonNullValueAfterRow|
+---+-----+-----+-------------------------+
| 0| Bob| 123| 123|
| 1| Jack| null| 456|
| 2|Brian| null| 456|
| 3| John| 456| 456|
| 4|Edgar| null| null|
+---+-----+-----+-------------------------+
问题:是否可以从我们使用 .first(...) 获得的行中获取另一个值? 我想获取该记录之后映射到第一个非空值的人的姓名:
+---+-----+-----+-------------------------+-------------------------+
| id| name|value|firstNonNullValueAfterRow|nameOfThatPerson |
+---+-----+-----+-------------------------+-------------------------+
| 0| Bob| 123| 123| Bob|
| 1| Jack| null| 456| John|
| 2|Brian| null| 456| John|
| 3| John| 456| 456| John|
| 4|Edgar| null| null| null|
+---+-----+-----+-------------------------+-------------------------+
这可以通过一些技巧来实现,但我想知道是否有办法使用 Spark 窗口函数来做到这一点。解决方法:
val idAndNameDF = df
.select("id", "name")
.withColumnRenamed("id", "id2")
.withColumnRenamed("name", "nameOfThatPerson")
df
.withColumn("idOfFirstNotNullValue", when(col("value").isNotNull, col("id")))
.withColumn("firstNonNullIdAfterRow", first("idOfFirstNotNullValue", true)
.over(window.rowsBetween(Window.currentRow, Window.unboundedFollowing)))
.join(idAndNameDF, col("firstNonNullIdAfterRow") === col("id2"),"left")
.show()
解决方法结果:
+---+-----+-----+---------------------+----------------------+----+----------------+
| id| name|value|idOfFirstNotNullValue|firstNonNullIdAfterRow| id2|nameOfThatPerson|
+---+-----+-----+---------------------+----------------------+----+----------------+
| 0| Bob| 123| 0| 0| 0| Bob|
| 1| Jack| null| null| 3| 3| John|
| 2|Brian| null| null| 3| 3| John|
| 3| John| 456| 3| 3| 3| John|
| 4|Edgar| null| null| null|null| null|
+---+-----+-----+---------------------+----------------------+----+----------------+
【问题讨论】:
【参考方案1】:是和否。不,不是,如果您的意思是它应该是同一个窗口子句或整体子句的一部分。是的,如果你做一些额外的事情。
也就是说,你的解决方法是正确的。
它们是两个不同的方面:
查找第一个“未来”非空事件 然后查找该事件的相关数据。这是有道理的。您应该将其视为子查询情况。
【讨论】:
以上是关于Spark Window 函数:是不是可以直接从使用第一个/最后一个函数找到的行中获取其他值?的主要内容,如果未能解决你的问题,请参考以下文章
Spark Structured Streaming Window() 函数 - GeneratedIterator 超过 64 KB
Spark Window 函数 - 获取每行分区中的所有记录,并保持顺序