使用spark中的其他csv文件更新csv文件

时间:2017-08-07 22:16:15

标签: scala apache-spark dataframe apache-spark-sql

我必须使用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()


  }
}

由于数据帧是不可变的,我无法对临时表进行更新,有什么方法可以实现它

1 个答案:

答案 0 :(得分:0)

您可以将outer join表格与c1列一起使用,并将table2的值复制到table1,如下所示。 重命名 table2的c2c3列,因为它们与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  |
+---+---+---+