由 cannot resolve ‘`a.stuID`‘ given input columns: [a.stuID, a.zhuanID, b.stuID, b.zhuanID]错误引发的思考

56 篇文章 4 订阅
47 篇文章 3 订阅

利用sparksql对两张表进行join,报错:

在这里插入图片描述
检查表中字段:

发现两张表内都存在stuID。

折腾了好久也没弄好,后来不甘心,将数据转为txt格式,没想到同样的代码 跑通了

这可太amazing了,打开两个文档反复对比了一下。并没有什么不同,直到身边的大神让我查看一下文件的编码才发现端倪:

## 预览文件

head -n 1 xxx.txt | od -c

linux 下的od命令可以查看 这篇博客

结果显示:
在这里插入图片描述发现csv文件的第一行第一列开头比txt多了三个字符,原因就在这:

再次打印 csv的列名,并查看每个的长度:

  var headerName = data.columns
    println("headName========",headerName.toList)
    for (x<- headerName){
      println("输出名称为:", x, " 输出长度为: ", x.length)
      println("逐次输出:~~~~~~~~~~~~~~~~~~")
      for(i<-0 until x.length){
        println("第", "个字符是::::", x(i).toByte)
      }
      println("@@@@@@@@@@@@@@结束@@@@@@@@@@@@")
    }

在这里插入图片描述发现 csv文件读取的第一个列名stuID本来长度为5,结果打印结果为6。出现隐藏字符,对隐藏字符进行打印发现是空字符,并且byte为-1。
所以才导致多表join时,找不到 a.stuID。到此,终于弄清楚了问题所在。

查阅了相关资料发现,是叫做BOM(Byte Order Mark),直接顺序标记,出现在文本文件的头部,Unicode编码标准中用于标识文件是采用哪种格式的编码。没有BOM 则表示是默认的ASCII
BOM主要用途是记录哪种编码格式。

找到问题,解决起来就容易了很多。

随后查阅到spark2.x已经可以通过对应api 正常读取csv文件:

    val data = spark.read.format("csv")
              .option("sep", ",")
              .option("header", true)
              .option("nullValue", "")
              .csv(p.input_pt)
      

这样就不会有问题了。

附:

本文用到的csv文件和txt文件的下载地址 密码:wg35

拓展: spark将字符(Char)与字节编码(Byte)的相互转化

字符转字节:toByte
字节转字符:toChar

var s = "abc"
for (x <- 0 until s.length){
    println(s(x).toByte)
    println(s(x).toByte.toChar.toString)
}
println(100.toChar)

println(("-1".toByte.toChar)==(-1.toChar))

结果:
s: String = abc
97
a
98
b
99
c
d
true

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值