在spark数据帧中执行字符串作为查询

时间:2017-08-09 19:23:05

标签: scala apache-spark dataframe

我正在使用以下数据:

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()

但是,由于查询中的字符串,我无法运行上面的代码。有什么方法可以执行吗?

1 个答案:

答案 0 :(得分:2)

你不能在字符串中编写scala-code而且&#34;执行&#34;这个字符串(类似于SELECT Stock.ID FROM Stock WHERE Stock.Producto IN ( SELECT producto FROM pedidos GROUP BY producto HAVING SUM(pedidos.cantidad) >= 100 // Your sale value ) )。也许有黑客可以实现这一点,但它绝对不是如何编写spark / scala代码。

我会建议这样的事情:

SELECT Stock.ID
FROM   Stock
WHERE  Stock.Producto IN ( 
    SELECT  Stock.ID, SUM(Pedidos.Cantidad)
    FROM    Pedidos
    INNER JOIN Stock ON Stock.ID = Pedidos.Lote
                     AND Stock.Producto = Pedidos.Producto
    GROUP BY Stock.ID, Pedidos.Producto
    HAVING  SUM(Pedidos.Cantidad) > 1000 --Sale Amount
)

或者使用for-loop并将eval定义为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

df_result

}