В записной книжке Scala на Apache Spark Databricks как правильно привести массив к типу decimal(30,0)?

Я пытаюсь преобразовать массив как Decimal(30,0) для использования в динамическом выборе как:

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_contains должен был быть массив, за которым следует значение с тем же типом элемента, но это [array, decimal (30, 0)]

Как правильно использовать десятичный формат (30,0) в записной книжке Spark Databricks Scala вместо десятичного (38,18)?

Любая помощь приветствуется!

1 ответ

Решение

Ты можешь сделать arrIds ан Array[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в Decimal с той же точностью и масштабом, что и тип, возвращаемый UDF. Так что ваши WHERE пункт должен быть:

WHERE array_contains(myArray(), cast(someTable.someColumn as Decimal(38, 18)))
Другие вопросы по тегам