我有一种简单的方法可以在spark sql上的多个列上调用sql。
例如,假设我有一个应该应用于大多数列的查询
select
min(c1) as min,
max(c1) as max,
max(c1) - min(c1) range
from table tb1
如果有多列,是否有办法对所有列执行查询,并获得一次结果。
与 df.describe 的方式类似。
答案 0 :(得分:1)
使用数据框中包含的元数据(本例中的列)(如果您还没有在范围内获取列名,可以通过spark.table("<table_name>")
获取),然后应用这些功能你想要并传递给df.select
(或df.selectExpr
)。
构建一些测试数据:
scala> var seq = Seq[(Int, Int, Float)]()
seq: Seq[(Int, Int, Float)] = List()
scala> (1 to 1000).foreach(n => { seq = seq :+ (n,r.nextInt,r.nextFloat) })
scala> val df = seq.toDF("id", "some_int", "some_float")
表示我们想要在所有列上运行的一些函数:
scala> val functions_to_apply = Seq("min", "max")
functions_to_apply: Seq[String] = List(min, max)
设置SQL列的最终Seq:
scala> var select_columns = Seq[org.apache.spark.sql.Column]()
select_columns: Seq[org.apache.spark.sql.Column] = List()
迭代要应用的列和函数来填充select_columns Seq:
scala> val cols = df.columns
scala> cols.foreach(col => { functions_to_apply.foreach(f => {select_columns = select_columns :+ expr(s"$f($col)")})})
运行实际查询:
scala> df.select(select_columns:_*).show
+-------+-------+-------------+-------------+---------------+---------------+
|min(id)|max(id)|min(some_int)|max(some_int)|min(some_float)|max(some_float)|
+-------+-------+-------------+-------------+---------------+---------------+
| 1| 1000| -2143898568| 2147289642| 1.8781424E-4| 0.99964607|
+-------+-------+-------------+-------------+---------------+---------------+