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

Spark SQL使用substring函数出现类型不匹配错误如何解决

问题原因
  • 首先你混淆了Spark SQL函数和Scala原生方法的签名差异:org.apache.spark.sql.functions.substring提供两类重载,一类接收(Column, Int, Int),仅适用于后两个参数是固定字面量的场景;另一类接收(Column, Column, Column),适用于参数是动态列计算结果的场景。你传入的instr(...) +17是列运算表达式,返回值永远是Column类型,不可能转为固定的字面量Int,你做的强转操作本身是无效的,因为Column是对全表每行计算逻辑的抽象,无法在Driver端直接转为固定值。
  • 报错的直接诱因大概率是你没有正确导入Spark的substring函数,编译器默认匹配了Scala原生String类的substring方法,才会提示要求入参为Int类型。
  • 你的代码还存在字段名笔误:计算起始位置时误用了manuscriptpolicy_ext_vehicledescription字段,和你要切割的vehicledescription字段不一致,会导致后续逻辑错误。
修复方案

首先确认导入Spark SQL函数依赖:

import org.apache.spark.sql.functions._

修正笔误后直接使用Column类型作为substring的入参即可,Spark原生支持该重载:

val registrationNumber = pc_policy_df.select(
  col("vehicledescription"),
  when(
    col("subproduct_ext") === "SpecialRiskOwnDamage" && instr(col("vehicledescription"), "Registration No.:") === 0,
    ""
  )
  .when(
    col("subproduct_ext") === "SpecialRiskOwnDamage" && instr(col("vehicledescription"), "Registration No.:") > 0,
    trim(
      substring(
        col("vehicledescription"),
        instr(col("vehicledescription"), "Registration No.:") + 17,
        locate(";", col("vehicledescription"), instr(col("vehicledescription"), "Registration No.:") + 17) - (instr(col("vehicledescription"), "Registration No.:") + 17)
      )
    )
  )
  .otherwise("registrationnumber")
  .as("R_NUMBER")
)

如果使用的Spark版本较低,不支持substring接收Column类型参数,可以用expr函数直接写SQL表达式实现,写法更简洁:

trim(expr("substring(vehicledescription, instr(vehicledescription, 'Registration No.:') + 17, locate(';', vehicledescription, instr(vehicledescription, 'Registration No.:') + 17) - (instr(vehicledescription, 'Registration No.:') + 17))"))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:54:03