0

会是怎样星火dataframes最好相当于SQL
星火更新列值的数据帧

update table1 set colx = "some value" where coly in (select coltab2 from table2 where [another condition)]

我有一些可行的解决方案,但我真的不是很满意。看起来真的很麻烦,我希望我错过simplier方式

首先,我得到的where子句的值(可能有几千,所以我不魔杖使用的集合)

val df2 = xxxx.select("coltab2") 
df2: org.apache.spark.sql.DataFrame = [coltab2: string] 

这个数据帧中包含我想保留在where子句中的所有值

然后,我使用table1执行左外部联接以在df2.coltab2=df1.coly上添加coltab2。如果添加的coltab2的值不为空,则表示它存在于table2中,因此我使用此条件更新来自原始table1(df1)的另一列,然后删除此添加的列coltab2,该列仅作为更新另一列的条件进行服务

val df_updated = df1.join(df2, df1("coly") === df2("coltab2"), "left_outer").withColumn("colx", when(!isnull($"coltab2"), "some value").otherwise(col("colx"))).drop(col("coltab2")) 

希望我完全地错了,有一种更有效的方式来做到这一点;)

+0

这似乎是完美的解决方案。有两项改进要做。 1而不是left_outer加入,你可以简单地使用left join和2 .otherwise(col(“colx”)),colx就是存在并且不能在when中使用。 –

回答

0

我觉得你有什么是良好的可读性很好地解决。如果想要的话,你可以探索另一种使用RDD的方法。与您的列清单不大的假设,你可以collect列的列表为set并相应地映射df1colx如下:

val df1 = Seq(
    ("x1", "y1"), ("x2", "y2"), ("x3", "y3") 
).toDF("colx", "coly") 

val df2 = Seq(
    ("y1"), ("y3"), ("y5") 
).toDF("coltab2") 

import org.apache.spark.sql.Row 

val colList: Set[String] = df2.rdd.map{ case Row(c: String) => c }.collect.toSet 

val dfUpdated = df1.rdd.map{ 
    case Row(x: String, y: String) => (if (colList contains y) "some value" else x, y) 
    }.toDF("colx", "coly") 

dfUpdated.show 
+----------+----+ 
|  colx|coly| 
+----------+----+ 
|some value| y1| 
|  x2| y2| 
|some value| y3| 
+----------+----+