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| 
+----------+----+