仅在存在(SQL或Scala)时选择字段



输入dataFrame可能并不总是具有所有列。在SQL或Scala中,我想创建一个选择语句,即使数据框没有列,它也不会出错,并且它将仅输出确实存在的列。

例如,此语句将起作用。

Select store, prod, distance from table
+-----+------+--------+
|store|prod  |distance|
+-----+------+--------+
|51   |42    |2     |
|51   |42    |5     |
|89   |44    |9     |

如果数据帧看起来如下,我希望相同的语句工作,只是忽略没有的内容,而只需输出现有列(在这种情况下为"商店"one_answers" prod")

+-----+------+
|store|prod  |
+-----+------+
|51   |42    |
|51   |42    |
|89   |44    |

您可以在列表中列出所有COLS的列表,要么硬编码或从其他元数据中进行准备并使用Intersect

val columnNames = Seq("c1","c2","c3","c4")
df.select( df.columns.intersect(columnNames).map(x=>col(x)): _* ).show()

您可以在Dataframe上使用columns方法。看起来这样:

val result = if(df.columns.contains("distance")) df.select("store", "prod", "distance") 
             else df.select("store", "prod")

编辑:

拥有许多这样的列,您可以将它们保存在数组中,例如colsfilter IT:

val selectedCols = cols.filter(col -> df.columns.contains("distance")).map(col)
val result = df.select(selectedCols:_*)

假设您使用扩展的SQL模板,例如select a,b,c from tab,您可以做以下类似的事情来获得所需的结果。

  1. 获取SQL字符串并将其转换为小写。
  2. 将SQL分开在空间或逗号上以获取数组中的单个单词
  3. 从上面的数组中删除"选择"one_answers"从SQL关键字。
  4. 现在您的最后一个索引是表名
  5. 首先是最后索引,但其中包含选择列的列表。
  6. 要获取所需的列,只需对DF2.Columns过滤。SQL中的列但不在表中的列将被过滤
  7. 现在使用各个部分构建SQL。
  8. 使用spark.sql(reqd_sel_string)来获取结果。

检查一下

scala> val df2 = Seq((51,42),(51,42),(89,44)).toDF("store","prod")
df2: org.apache.spark.sql.DataFrame = [store: int, prod: int]
scala> df2.createOrReplaceTempView("tab2")
scala> val sel_query="Select store, prod, distance from tab2".toLowerCase
sel_query: String = select store, prod, distance from tab2
scala> val tabl_parse = sel_query.split("[ ,]+").filter(_!="select").filter(_!="from")
tabl_parse: Array[String] = Array(store, prod, distance, tab2)
scala> val tab_name=tabl_parse(tabl_parse.size-1)
tab_name: String = tab2
scala> val tab_cols = (0 until tabl_parse.size-1).map(tabl_parse(_))
tab_cols: scala.collection.immutable.IndexedSeq[String] = Vector(store, prod, distance)
scala> val reqd_cols = tab_cols.filter( x=>df2.columns.contains(x))
reqd_cols: scala.collection.immutable.IndexedSeq[String] = Vector(store, prod)
scala> val reqd_sel_string = "select " + reqd_cols.mkString(",") + " from " + tab_name
reqd_sel_string: String = select store,prod from tab2
scala> spark.sql(reqd_sel_string).show(false)
+-----+----+
|store|prod|
+-----+----+
|51   |42  |
|51   |42  |
|89   |44  |
+-----+----+

scala>

相关内容

  • 没有找到相关文章

最新更新