我想输入看起来像 -
的数据"58;""management"";""married"";""tertiary"";""no"";2143;""yes"";""no"";""unknown"";5;""may"";261;1;-1;0;""unknown"";""no"""
"44;""technician"";""single"";""secondary"";""no"";29;""yes"";""no"";""unknown"";5;""may"";151;1;-1;0;""unknown"";""no"""
"33;""entrepreneur"";""married"";""secondary"";""no"";2;""yes"";""yes"";""unknown"";5;""may"";76;1;-1;0;""unknown"";""no"""
"47;""blue-collar"";""married"";""unknown"";""no"";1506;""yes"";""no"";""unknown"";5;""may"";92;1;-1;0;""unknown"";""no"""
我的create table语句为 -
sqlContext.sql("create table dummy11(age int, job string, marital string, education string, default string, housing string, loan string, contact string, month string, day_of_week string, duration int, campaign int, pday int, previous int, poutcome string, emp_var_rate int, cons_price_idx int, cons_conf_idx int, euribor3m int, nr_employed int, y string)row format delimited fields terminated by ';'")
当我运行声明 -
时sqlContext.sql("from dummy11 select age").show()
OR
sqlContext.sql("from dummy11 select y").show()
它返回NULL
值而不是正确的值,但其他值是可见的
那我该如何纠正呢?
答案 0 :(得分:0)
当您使用Hive QL语法时,您需要在处理之前验证输入数据。
在您的数据中,很少有记录的列数少于DDL中定义的实际列数。
因此,对于那些记录,其余列(从last)被设置为NULL;因为该行没有足够的值。
这就是为什么,最后一栏y
的值为NULL
。
此外,在DDL中,第一个字段的数据类型为INT
;但在记录中,第一个字段值是:
"58
"44
"33
由于"
,值未按类型转换为INT
;将字段值设置为NULL
。
根据您提供的DDL和数据,值设置为:
age "58
job ""management""
marital ""married""
education ""tertiary""
default ""no""
housing 2143
loan ""yes""
contact ""no""
month ""unknown""
day_of_week 5
duration ""may""
campaign 261
pday 1
previous -1
poutcome 0
emp_var_rate ""unknown""
cons_price_idx ""no""
cons_price_idx NULL
cons_conf_idx NULL
euribor3m int NULL
nr_employed NULL
y NULL
检查最后5列的NULL
值。
因此,如果不是这样,您需要在继续之前先验证数据。
对于列age
,如果您需要INT
类型,请清除数据以删除不需要的"
字符。
解决方法强>
作为解决方法,您可以在开始时将age
定义为STRING
,因为使用spark变换来解析第一个字段并将其转换为INT
import org.apache.spark.sql.functions._
val ageInINT = udf { (make: String) =>
Integer.parseInt(make.substring(1))
}
df.withColumn("ageInINT", ageInINT(df("age"))).show
此处df
是您执行hive DDL时创建的数据框,其中列age
为sTRING
。
Nnow,您可以对新列ageInINT
执行操作,而不是使用age
值对列INTEGER
执行操作。
答案 1 :(得分:0)
由于您的数据在年龄之前包含"
,因此它被视为字符串。在代码中,您已将其定义为int
,因此sql解析器正在尝试查找整数值,因此您将获得null
记录。使用age int
更改age string
,您就可以看到结果了。
请参阅下面的工作示例使用Spark HiveContext
。
import org.apache.spark.sql.hive.HiveContext;
import org.apache.spark.sql.types._
import org.apache.spark.SparkContext
import org.apache.spark.SparkConf
val sc = new SparkContext(conf)
val sqlContext = new HiveContext(sc)
sqlContext.sql("create external table dummy11(age string, job string, marital string, education string, default string, housing string, loan string, contact string, month string, day_of_week string, duration int, campaign int, pday int, previous int, poutcome string, emp_var_rate int, cons_price_idx int, cons_conf_idx int, euribor3m int, nr_employed int, y string)row format delimited fields terminated by ';' location '/user/skumar143/stack/'")
sqlContext.sql("select age, job from dummy11").show()
其输出:
+---+----------------+
|age| job|
+---+----------------+
|"58| ""management""|
|"44| ""technician""|
|"33|""entrepreneur""|
|"47| ""blue-collar""|
+---+----------------+