我尝试将新数据集与旧数据集合并,我为每种表类型都有一个Seq [String]主键,以及一个旧数据帧和一个具有相同模式的新数据帧。
如果主键列值匹配,我想将旧数据框中的行替换为新数据框中的行,如果它们不匹配,我想要添加该行。
到目前为止,我有这个:
val finalFrame: DataFrame = oldDF.withColumn("old/new",lit("1"))
.union(newDF.withColumn("old/new",lit("2")))
.dropDuplicates(primaryKeySet)
我添加一个1和2的文字列,以跟踪哪些行,将它们组合在一起,并根据主键列名称的Seq [String]删除重复项。这个解决方案的问题在于它不允许我指定从表中删除哪些重复项,如果我可以使用" 1"来指定重复项。被删除是最佳的,但我可以接受替代解决方案。
答案 0 :(得分:1)
把我的头砸了一会儿,想出了一个把戏。我的主键是一个序列,因此无法直接进入窗口函数中的partitionBy,所以我这样做了:
val windowFunction = Window.partitionBy(primaryKeySet.head, primaryKeySet.tail: _*).orderBy(desc("old/new"))
val duplicateFreeFinalDF = finalFrame.withColumn("rownum", row_number.over(windowFunction)).where("rownum = 1").drop("rownum").drop("old/new")
基本上只是使用了vararg扩展,所以partitionBy会占用我的列表,然后是一个rownum窗口函数,所以我可以确保在重复的情况下获得最新的副本。