基于Scala的Spark SQL需求:将两查询结果转Double后做除法
解决方案:Spark SQL中转换数值类型并完成除法运算
嘿,我来帮你搞定这个问题!你现在需要把两个count查询的结果转成Double类型再做除法,这里有两种实用的方法,根据你的需求选就行:
方法一:直接在SQL查询中完成转换与计算(推荐)
这种方法更高效,因为Spark会在查询阶段直接处理所有逻辑,不用把中间结果单独存成DataFrame再处理。你可以写一个SQL语句,一次性统计订阅数、总数并完成类型转换和除法:
val subscriptionRateDF = sqlContext.sql(""" SELECT CAST(COUNT(CASE WHEN y='yes' THEN 1 END) AS DOUBLE) / CAST(COUNT(*) AS DOUBLE) AS subscription_rate FROM bankdata """) // 查看结果 subscriptionRateDF.show()
逻辑说明:
COUNT(CASE WHEN y='yes' THEN 1 END):专门统计y='yes'的记录数,和你单独的noofsubscribed查询效果一致CAST(xxx AS DOUBLE):把BigInt类型的count结果转换成Double,避免整数除法导致精度丢失- 直接在SQL中完成除法,最终得到的DataFrame里就是计算好的订阅率
方法二:基于已有的两个DataFrame进行转换计算
如果一定要保留你原来的noofentry和noofsubscribed这两个DataFrame,那可以把它们的数值提取出来转换成Double后再计算:
// 提取总条目数并转为Double val totalEntries = noofentry.head().getLong(0).toDouble // 提取订阅数并转为Double val subscribedEntries = noofsubscribed.head().getLong(0).toDouble // 计算除法 val subscriptionRate = subscribedEntries / totalEntries // 打印结果 println(s"订阅比例: $subscriptionRate")
步骤说明:
head():因为count查询只会返回一行结果,所以用这个方法取出第一行数据getLong(0):取出第一列的BigInt类型数值(count结果默认是bigint)toDouble:把BigInt转换成Double类型,这样除法会保留小数精度- 最后直接做除法运算就能得到你要的结果
小提示:如果你用的是Spark 2.0及以上版本,建议使用
spark.sql(SparkSession的API)代替sqlContext.sql,这是官方推荐的新用法哦~
内容的提问来源于stack exchange,提问作者Amit Porwal
相关产品推荐
相关产品推荐

