首页 > 解决方案 > 铸造时 Spark Decimal Precision 和 Scale 似乎错误

问题描述

阅读文档,Spark DataType BigDecimal(precision, scale) 意味着

所以当我将一个值转换为十进制时

scala> val sss = """select cast(1.7142857343 as decimal(9,8))"""
scala> spark.sql(sss).show
+----------------------------------+
|CAST(1.7142857343 AS DECIMAL(9,8))|
+----------------------------------+
|                        1.71428573|  // It has 8 decimal digits
+----------------------------------+

但是当我将值转换为 10.0 以上时,我得到 NULL

scala> val sss = """select cast(12.345678901 as decimal(9,8))"""
scala> spark.sql(sss).show
+----------------------------+
|CAST(11.714 AS DECIMAL(9,8))|
+----------------------------+
|                        null|
+----------------------------+

我希望结果是12.3456789

标签: scalaapache-spark

解决方案


转换十进制火花在内部验证提供的模式十进制(9,8)大于 12.345678901 实际模式十进制(11,9)。如果是,则意味着可以安全地将数字转换为提供的模式,而不会丢失任何精度或范围。看看 org.apache.spark.sql.types.DecimalType.isWiderThan()

但是,在上述情况下,decimal(11,9) 不能转换为 decimal(9,8),因此它返回 null。

//MAX_PRECISION = 38
val sss = """select cast(12.345678901 as decimal(38,7))"""
spark.sql(sss1).show(10)
+-----------------------------------+
|CAST(12.345678901 AS DECIMAL(38,8))|
+-----------------------------------+
|                         12.3456789|
+-----------------------------------+

推荐阅读