spark - nvl 函数数据类型不匹配错误

Posted

技术标签:

【中文标题】spark - nvl 函数数据类型不匹配错误【英文标题】:spark - nvl function data type mismatch error 【发布时间】:2016-12-14 09:22:29 【问题描述】:

在 Spark sql 中使用 JDBC 数据源,我们尝试运行以下查询

select nvl( columnName , 1.0) from tablename

给出错误

cannot resolve 'nvl(tablename.`columnname`, 1.0BD)' due to data type mismatch: input to function coalesce should all be the same type, but it's [decimal(38,10), decimal(2,1)]

我知道我们可以解决这个问题

select nvl( columnname , CAST( 1.0 as decimal(38,10))) from tablename

看起来我需要找到每一列的数据类型并转换为它。

    有没有其他办法处理? 我可以在加载 csv 格式的数据帧时预先给出架构定义吗? [https://issues.apache.org/jira/browse/SPARK-16848] 如何为每一列转换加载的 Dataframe 数据类型。

【问题讨论】:

【参考方案1】:
    您可以在 NVL 上使用 Coalesce 代替。合并的输入被强制转换为“最佳”通用数据类型。 JDBC 连接使用数据库架构作为其架构,因此无法预先提供架构。

    您可以通过添加另一个 select 将所有列转换为不同的数据类型,这在数据帧/数据集 API 中很容易:

    // Create some toy data.
    val df = spark.range(100).select($"id", (rand(2) * 10).as("a"))
    df.printSchema
    
    // Define the casts.
    val casts = Seq(col("id").cast("int"), col("a").cast("int"))
    
    // Apply the casts.
    df.select(casts: _*).printSchema
    

【讨论】:

感谢您的回复。我理解第 1 点和第 2 点的答案,关于第 3 点“选择”操作的开销是什么。 select 的开销很低(尤其是使用代码生成时);它可能比某些数据源中发生的转换更快。

以上是关于spark - nvl 函数数据类型不匹配错误的主要内容,如果未能解决你的问题,请参考以下文章

数据库中的 NVL() 方法怎么用 ?

说说 Oracle 的 NVL 与 NVL2 函数

在oracle数据库中nvl()是啥函数?

Spark - aggregateByKey 类型不匹配错误

Spark UDF 类型不匹配错误

OpenRecordSet 的数据类型不匹配错误