2017-08-09 81 views
1

我使用了以下數據:執行字符串作爲火花數據查詢幀

數據DF1:

c1,c2,c3,c4 
k1,i,aa,k 
k5,j,ee,l 

數據DF2:

c1,avc2,c3,avc4 
k1,a,aa,e 
k2,b,bb,f 
k3,c,cc,g 
k4,d,dd,h 

我想創建一個動態查詢字符串根據條件使用以下代碼:

val PRIM_CHECK="c1,c3".split(",").toList 
val COLUMN_UNCHANGE="c4".split(",").toList 
var qb = new ListBuffer[String]() 
val df3=df1.join(df2,seq("c1","c3"), "outer") 
    for(i<-avro_inp.columns) 
     { 
     if(PRIM_CHECK.contains(i)) 
     { 

     } 
     else if(COLUMN_UNCHANGE.contains(i)) 
     { 
     qb+=""".withColumn(""""+i+"""", when('"""+""+i+""".isNotNull,'"""+i+""").otherwise('av"""+""+i+"""))""" 
     } 
     else 
     { 
      qb+=""".withColumn(""""+i+"""", when('av"""+""+i+""".isNull,'"""+i+""").otherwise('av"""+""+i+"""))""" 
     } 

    } 

    val check=qb.mkString 

不過,我想運行下面的代碼

df3.+""+check+""+.show() 

但是,我不能運行,因爲在查詢字符串上面的代碼。有什麼方法可以執行它嗎?

+0

耶穌,這是醜陋:) –

+0

@RaphaelRoth我需要創建一個有很多條件的動態查詢。我沒有找到更好的方法去做。 – sri

+0

但我無法想象這個工作,你寫在字符串scala代碼,這將不會執行 –

回答

2

你不能在一個字符串中編寫scala-code並且「執行」這個字符串(類似於eval)。也許有黑客來實現這一點,但絕對不是如何寫火花/斯卡拉代碼。使用一個for循環和df_result定義爲var

import org.apache.spark.sql.functions._ 

val df_result = avro_inp.columns.foldLeft(df3) { case (df, i) => 
    if (PRIM_CHECK.contains(i)) { 
    df 
    } 
    else if (PRIM_CHECK.contains(i)) { 
    df.withColumn(i, when(col(i).isNotNull, col(i)).otherwise(col("av" + i))) 
    } 
    else { 
    df.withColumn(i, when(col(i).isNull, col(i)).otherwise(col("av" + i))) 
    } 
} 

df_result.show 

或者::

我建議這樣的事情

var df_result = df3 

for (i <- avro_inp.columns) { 
    if (PRIM_CHECK.contains(i)) { 
    } 
    else if (PRIM_CHECK.contains(i)) { 
    df_result = df_result.withColumn(i, when(col(i).isNotNull, col(i)).otherwise(col("av" + i))) 
    } 
    else { 
    df_result = df_result.withColumn(i, when(col(i).isNull, col(i)).otherwise(col("av" + i))) 
    } 

}