我想在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()时,我没有在使用另一个聚合函数中的聚合函数时收到任何错误,但是为什么在第二个聚合函数中却出错了? >
答案 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。我注意到按照总和,别名似乎不起作用,因此请解决此问题并在上面进行左比较。同样,您将需要针对自己的具体情况进行定制,这是我的一般研究模块等的一部分。