You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark中Decimal类型相乘无溢出却返回NULL的问题咨询

Spark Decimal相乘返回NULL的原因解析

问题场景

将类型为DecimalType(38,10)和DecimalType(38,16)的两列数值相乘,结果列类型被推导为DecimalType(38,22),且已通过配置禁用精度损失(spark.sql.decimalOperations.allowPrecisionLoss=false)。按照官方文档描述,仅当数值过大导致整数部分溢出时结果才会返回NULL,但实际中即使是30858938444.540 × 1这类简单操作,结果也返回NULL。

核心原因

Spark对Decimal类型的乘法运算遵循以下逻辑:

  1. 中间结果计算:两个Decimal相乘时,中间结果的精度为p1 + p2(即38+38=76),小数位数为s1 + s2(即10+16=26)。
  2. 目标类型适配检查:当禁用精度损失时,Spark要求中间结果必须无损适配到目标结果类型DecimalType(38,22),既不能截断小数位,也不能让整数部分溢出。
  3. 触发NULL的场景:示例中的30858938444.540 × 1得到的中间结果小数位是26位,但目标类型仅支持22位小数。由于禁用了精度损失,Spark不允许截断多余的4位小数,因此直接返回NULL——这并非整数部分溢出,而是小数位精度无法无损保留导致的。

验证解决方法

  • 降低参与计算的Decimal列小数位数:比如将其中一列的小数位调整为12,相乘后中间结果小数位为22,刚好匹配目标类型,可正常返回结果。
  • 开启允许精度损失配置:设置spark.sql.decimalOperations.allowPrecisionLoss=true,Spark会自动截断多余的小数位,返回符合目标类型的结果。

内容的提问来源于stack exchange,提问作者Grevioos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 12:17:04