源表pdwqy_qxzh_piu字段类型:
如代码所示,在计算过程时,RFHL计算结果总是为null。
代码:
//读取数据
val data: DataFrame = spark.read.format("jdbc")
.option("url", "jdbc:mysql://21.76.120.96:3306/us_app")
.option("dbtable", "pdwqy_qxzh_piu")
.option("user", "root")
.option("password", "zhbr@1234")
.load()
data.createTempView("PIU_Table")
val resultData = spark.sql(
"""
|SELECT
| T1.TG_ID,
| date(T1.DATA_DATE) DATA_DATE,
| T1.I1,
| T1.I2,
| T1.I3,
| ROUND(AVG(T2.FZL), 4) PJFZL,
| ROUND(MAX(T2.FZL), 4) ZDFZL,
| ROUND(MIN(T2.FZL), 4) ZXFZL,
| case when MAX(T2.FZL) != 0 then round((AVG(T2.FZL)/MAX(T2.FZL))*100,4) else 0 end RFHL
| FROM PIU_Table T1 JOIN PIU_Table T2
| ON T1.TG_ID = T2.TG_ID
| and date(t1.data_date) = date(T2.data_date)
| where t1.SJD='96'
| GROUP BY T1.I1,
| T1.I2,
| T1.I3,
| T1.TG_ID,
| date(T1.DATA_DATE)
""".stripMargin)
//打印字段类型
resultData.printSchema()
//将数据保存到表
ConnOracleUtile.writeData(resultData,"pdwqy_qxzh_sbyxsj_copy")
通过打印字段类型字段类型,得知数据类型AVG(T2.FZL)和MAX(T2.FZL)均为decimal:
而计算完的结果,RFHL为null。也就是两个decimal类型的值相除的结果为null。
解决方法:
自定义一个求两个decimal类型数值相除的函数:
//自定义函数
spark.udf.register("chufa", (num1: java.math.BigDecimal ,num2: java.math.BigDecimal) => {
(num1.toString.toDouble/num2.toString.toDouble)
})
val resultData = spark.sql(
"""
|SELECT
| T1.TG_ID,
| yearMonthDay(T1.DATA_DATE) DATA_DATE,
| T1.I1,
| T1.I2,
| T1.I3,
| ROUND(AVG(T2.FZL), 4) PJFZL,
| ROUND(MAX(T2.FZL), 4) ZDFZL,
| ROUND(MIN(T2.FZL), 4) ZXFZL,
| case when MAX(T2.FZL) != 0 then round(chufa(AVG(T2.FZL),MAX(T2.FZL))*100,4) else 0 end RFHL
| FROM PIU_Table T1 JOIN PIU_Table T2
| ON T1.TG_ID = T2.TG_ID
| and yearMonthDay(t1.data_date) = yearMonthDay(T2.data_date)
| where t1.SJD='96'
| GROUP BY T1.I1,
| T1.I2,
| T1.I3,
| T1.TG_ID,
| yearMonthDay(T1.DATA_DATE)
""".stripMargin)
resultData.printSchema()
//将数据保存到表
ConnOracleUtile.writeData(resultData,"pdwqy_qxzh_sbyxsj_copy")
这时目标表中RFHL字段就有了数据:
原因探究:
参考此文章https://issues.apache.org/jira/browse/SPARK-22036?jql=project%20%3D%20SPARK%20AND%20text%20~%20"BigDecimal"中对于SPARK-22036bug的描述:BigDecimal multiplication sometimes returns null
spark确实存在此版本bug,两个BigDecimal类型的数相乘,有时会返回null。
但是关于两个BigDecimal类型的数相除是否也存在这样的问题,本人暂时还没有找到相关的说明。
那可不可以这样猜想,a/b也可以看做是a*(1/b)呢,仅作为一种猜想吧。
转载:https://blog.csdn.net/weixin_44455388/article/details/100984844
查看评论