在apachespark databricks上的scala笔记本中,如何正确地将数组强制转换为decimal(30,0)?

kokeuurv  于 2021-05-18  发布在  Spark
关注(0)|答案(1)|浏览(387)

我正在尝试将数组强制转换为十进制(30,0),以便在select中使用:

WHERE array_contains(myArrayUDF(), someTable.someColumn)

但是,当用以下材料浇铸时:

val arrIds = someData.select("id").withColumn("id", col("id")
                .cast(DecimalType(30, 0))).collect().map(_.getDecimal(0))

databricks接受这一点,但是签名看起来已经错了:intarrsurrids:array[java.math.bigdecimal]=array(2181890000000,…)//即bigdecimal
导致以下错误:
sql语句中出错:analysisexception:无法解析。。由于数据类型不匹配:函数array\u contains的输入应该是array后跟一个具有相同元素类型的值,但它是[array<decimal(38,18)>,decimal(30,0)]
如何在spark databricks scala笔记本中正确地转换为十进制(30,0)而不是十进制(38,18)?
感谢您的帮助!

svgewumm

svgewumm1#

你可以让 arrIdsArray[Decimal] 使用以下代码:

import org.apache.spark.sql.functions.col
import org.apache.spark.sql.types.{Decimal, DecimalType}

val arrIds = someData.select("id")
  .withColumn("id", col("id").cast(DecimalType(30, 0)))
  .collect()
  .map(row => Decimal(row.getDecimal(0), 30, 0))

但是,它不会解决您的问题,因为一旦您创建了用户定义的函数,您就失去了精度和比例,正如我在这个答案中解释的那样
为了解决你的问题,你需要把柱子 someTable.someColumn 与udf返回的类型具有相同的精度和小数位数。所以你的 WHERE 条款应为:

WHERE array_contains(myArray(), cast(someTable.someColumn as Decimal(38, 18)))

相关问题