输入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")
编辑:
拥有许多这样的列,您可以将它们保存在数组中,例如cols
和filter
IT:
val selectedCols = cols.filter(col -> df.columns.contains("distance")).map(col)
val result = df.select(selectedCols:_*)
假设您使用扩展的SQL模板,例如select a,b,c from tab
,您可以做以下类似的事情来获得所需的结果。
- 获取SQL字符串并将其转换为小写。
- 将SQL分开在空间或逗号上以获取数组中的单个单词
- 从上面的数组中删除"选择"one_answers"从SQL关键字。
- 现在您的最后一个索引是表名
- 首先是最后索引,但其中包含选择列的列表。
- 要获取所需的列,只需对DF2.Columns过滤。SQL中的列但不在表中的列将被过滤
- 现在使用各个部分构建SQL。
- 使用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>