我必须使用table2更新table1,如果table2中的主键不存在于table2中,则将table2的整行追加到table1。如果table1的主键出现在table2中,那么table1的所有列都要更新,除非table1的c3,其值为table2。
表1
c1 c2 c3
... .... ...
k1 a e
k2 b f
k3 c g
k4 d h
表2
c1 c2 c3
... .... ...
k1 i k
k5 j l
必需的输出
c1 c2 c3
... ... ...
k1 i e
k2 b f
k3 c g
k4 d h
k5 j l
我尝试了以下代码
import org.apache.spark.sql.{Row, SQLContext}
import org.apache.spark.{SparkConf, SparkContext}
object Update {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setAppName("tabUP").setMaster("local[2]")
val sc = new SparkContext(sparkConf)
val sqlContext = new SQLContext(sc)
val df1 = sqlContext.read.format("com.databricks.spark.csv").option("header", "true").load("f1.csv")
val df2= sqlContext.read.format("com.databricks.spark.csv").option("header", "true").load("f2.csv")
df1.registerTempTable("tab1")
df2.registerTempTable("tab2")
val df3=sqlContext.sql("UPDATE tab1,tab2 SET tab1.val2 = tab2.val1,tab1.val3 = tab2.val3 WHERE tab1.val1 = tab2.val1").show()
}
}
由于数据帧是不可变的,我无法对临时表进行更新,有什么方法可以实现它
答案 0 :(得分:0)
您可以将outer join
表格与c1
列一起使用,并将table2
的值复制到table1
,如下所示。 重命名 table2的c2
和c3
列,因为它们与table1具有相同的名称。
val tempTable2 = table2.select('c1, 'c2.as("c22"), 'c3.as("c23"))
import org.apache.spark.sql.functions._
table1.join(tempTable2, Seq("c1"), "outer")
.withColumn("c2", when('c22.isNotNull, 'c22).otherwise('c2))
.withColumn("c3", when('c3.isNull, 'c23).otherwise('c3))
.drop("c22", "c23")
您应该输出
+---+---+---+
|c1 |c2 |c3 |
+---+---+---+
|k2 |b |f |
|k4 |d |h |
|k5 |j |l |
|k1 |i |e |
|k3 |c |g |
+---+---+---+