Выберите поле, только если оно существует (SQL или Scala) - PullRequest
1 голос
/ 18 марта 2019

Фрейм входных данных не всегда может содержать все столбцы.В SQL или SCALA я хочу создать оператор выбора, в котором, даже если у фрейма данных нет столбца, он не выдаст ошибку и выведет только существующие столбцы.

Например, этот операторбудет работать.

Select store, prod, distance from table

+-----+------+--------+
|store|prod  |distance|
+-----+------+--------+
|51   |42    |2     |
|51   |42    |5     |
|89   |44    |9     |

Если фрейм данных выглядит так, как показано ниже, я хочу, чтобы тот же оператор работал, просто игнорировал то, чего не было, и просто выводил существующие столбцы (в данном случае 'store' и 'prod')

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

Ответы [ 3 ]

2 голосов
/ 18 марта 2019

Вы можете иметь список всех столбцов в списке, жестко запрограммированных или подготовленных из других метаданных, и использовать пересечение

val columnNames = Seq("c1","c2","c3","c4")

df.select( df.columns.intersect(columnNames).map(x=>col(x)): _* ).show()
2 голосов
/ 18 марта 2019

Вы можете использовать метод columns на Dataframe.Это будет выглядеть так:

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:_*)
1 голос
/ 18 марта 2019

Предполагая, что вы используете расширенный шаблон SQL, например select a,b,c from tab, вы можете сделать что-то вроде ниже, чтобы получить требуемые результаты.

  1. Получить строку sql и преобразовать ее в нижний регистр.
  2. Разделить sql на пробел или запятую, чтобы получить отдельные слова в массиве
  3. Удалить "select"и "from" из указанного выше массива, поскольку они являются ключевыми словами 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...