将MS-SQL查询转换为Spark SQL时出现问题

时间:2018-09-05 07:12:01

标签: scala apache-spark apache-spark-sql

我想在Spark中转换此基本SQL查询

select Grade, count(*) * 100.0 / sum(count(*)) over()
from StudentGrades
group by Grade

我曾尝试在这种火花中使用开窗功能

val windowSpec = Window.rangeBetween(Window.unboundedPreceding,Window.unboundedFollowing)

df1.select(
$"Arrest"
).groupBy($"Arrest").agg(sum(count("*")) over windowSpec,count("*")).show()


+------+-------------------------------------------------------------------- 
----------+--------+
|Arrest|sum(count(1)) OVER (RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED 
FOLLOWING)|count(1)|
+------+-------------------------------------------------------------------- 
----------+--------+
|  true|                                                                        
665517|  184964|
| false|                                                                        
665517|  480553|
+------+------------------------------------------------------------------------------+--------+

但是当我尝试除以count(*)时,会遇到错误

df1.select(
$"Arrest"
).groupBy($"Arrest").agg(count("*")/sum(count("*")) over 
windowSpec,count("*")).show()

不允许在另一个聚合函数的参数中使用聚合函数。请在子查询中使用内部聚合函数。;

我的问题是,当我在第一个查询中已经在sum()中使用count()时,我没有在使用另一个聚合函数中的聚合函数时收到任何错误,但是为什么在第二个聚合函数中却出错了? >

1 个答案:

答案 0 :(得分:1)

一个例子:

import org.apache.spark.sql.expressions._
import org.apache.spark.sql.functions._

val df = sc.parallelize(Seq(
   ("A", "X", 2, 100), ("A", "X", 7, 100), ("B", "X", 10, 100),
   ("C", "X", 1, 100), ("D", "X", 50, 100), ("E", "X", 30, 100)
    )).toDF("c1", "c2", "Val1", "Val2")

val df2 = df
  .groupBy("c1")
  .agg(sum("Val1").alias("sum"))
  .withColumn("fraction", col("sum") /  sum("sum").over())

df2.show

您将需要根据自己的情况进行调整。例如。计数而不是总和。如下:

val df2 = df
  .groupBy("c1")
  .agg(count("*"))
  .withColumn("fraction", col("count(1)") /  sum("count(1)").over())

返回:

+---+--------+-------------------+
| c1|count(1)|           fraction|
+---+--------+-------------------+
|  E|       1|0.16666666666666666|
|  B|       1|0.16666666666666666|
|  D|       1|0.16666666666666666|
|  C|       1|0.16666666666666666|
|  A|       2| 0.3333333333333333|
+---+--------+-------------------+

您可以执行x100。我注意到按照总和,别名似乎不起作用,因此请解决此问题并在上面进行左比较。同样,您将需要针对自己的具体情况进行定制,这是我的一般研究模块等的一部分。