hive不以科学计数法输出,hive计数法输出
Hive中int , float , double这些数值类型在存储⼤额度数字时,在前端展现上总是使⽤科学计数法来表⽰,例如:
hive> lect pow(10,8) from dual;
OK
1.0E8气急败坏的意思是什么
其实⽆论是普通的表⽰⽅式还是科学计数法表⽰,只是⼀个习惯问题,结果都是⼀样的。可是不能理解的是当把数值类型转化成字符串类型以后Hive竟然把数值转换成了科学计数法表⽰的字符串⽽⾮数值本⾝的字符串,例如:
hive> lect cast(pow(10,8) as string) from dual;
OK
1.0E8
这样问题就来了,很对时候业务需求要求数值必须存储为字符串类型,但是如果存储的是⼀个科学计数法表⽰的字符串,那就失去了数值本⾝的含义,例如再想把这个字符串转回数值类型就会出现转换错误:
hive> lect cast('1.0E8' as int) from dual;
OK
1
因此,需要有⼀种⽅法在把数值类型转换成字符串类型时,强制Hive不要转换成科学计数法表⽰。
我查找了很多资料没有找到Hive中例如⼀个参数可以做这个控制。因此只能采取其他策略进⾏转换。
当我们要转换的数值只有整型⽽没有⼩数时,我们可以先把数值类型转换成bigint类型,使⽤bigint类型存储的数值不会采⽤科学计数法表⽰,例如:
hive> lect cast(pow(10,8) as bigint) from dual;
OK
100000000
hive> lect cast(cast(pow(10,8) as bigint) as string) from dual;
OK
100000000
未嫁时但是由于bigint只能存储整型,当我们处理浮点数时这个⽅法就不灵了。
不得已我只能采⽤字符串解析这种最原始的⽅法:
问卷说明以下是我写的将科学计数法表⽰的字符串转换为普通表⽰法表⽰的字符串的转换SQL:古诗字帖
ca
--处理⾮科学计数法表⽰的字符串
when length(regexp_extract('字符串','([0-9]+\\.)([0-9]+)(E-*[0-9]+)',2))=0
then '字符串'
-
-处理整数
吐鲁番盆地when length(regexp_extract('字符串','([0-9]+\\.)([0-9]+)(E[0-9]+)',2))<=cast(regexp_extract('字符串','(E)([0-9]+)',2) as int)
then rpad(regexp_replace(regexp_extract('字符串','([^E]+)',1),'\\.',''),cast(regexp_extract('字符串','(E)([0-9]+)',2) as int)+1,'0')
--处理⼩数
when length(regexp_extract('字符串','([0-9]+\\.)([0-9]+)(E[0-9]+)',2))>cast(regexp_extract('字符串','(E)([0-9]+)',2) as int)
then concat(substr(regexp_replace(regexp_extract('字符串','([^E]+)',1),'\\.',''),1,cast(regexp_extract('字符串','(E)([0-9]+)',2) as int)+1),'\.',
substr(regexp_replace(regexp_extract('字符串','([^E]+)',1),'\\.',''),cast(regexp_extract('字符串','(E)([0-9]+)',2) as int)+2))
--处理类似“3.4E-6”这种字符串
when '字符串' regexp 'E-'
描写花then concat('0.',repeat('0',cast(regexp_extract('字符串','(E)(-)([0-9]+)',3) as int)-1),regexp_replace(regexp_extract('字符串','(.+)(E)',1),'\\.',''))
el '字符串'
end
套的形近字
例如要处理“1.5602200465E8”这样⼀个字符串:
hive> lect
> ca
> when length(regexp_extract('1.5602200465E8','([0-9]+\\.)([0-9]+)(E-*[0-9]+)',2))=0 then '1.5602200465E8'
> when length(regexp_extract('1.5602200465E8','([0-9]+\\.)([0-9]+)(E[0-9]+)',2))<=cast(regexp_extract('1.5602200465E8','(E)([0-9]+)',2) as int)
> then rpad(regexp_replace(regexp_extract('1.5602200465E8','([^E]+)',1),'\\.',''),cast(regexp_extract('1.5602200465E8','(E)([0-9]+)',2) as int)+1,'0')
> when length(regexp_extract('1.5602200465E8','([0-9]+\\.)([0-9]+)(E[0-9]+)',2))>cast(regexp_extract('1.5602200465E8','(E)([0-9]+)',2) as int)
> then concat(substr(regexp_replace(regexp_extract('1.5602200465E8','([^E]+)',1),'\\.',''),1,cast(regexp_extract('1.5602200465E8','(E)([0-9]+)',2) as int)+1),'\.',
> substr(regexp_replace(regexp_extract('1.5602200465E8','([^E]+)',1),'\\.',''),cast(regexp_extract('1.5602200465E8','(E)([0-9]+)',2) as int)+2))
> when '1.5602200465E8' regexp 'E-'
> then concat('0.',repeat('0',cast(regexp_extract('1.5602200465E8','(E)(-)([0-9]+)',3) as int)-
1),regexp_replace(regexp_extract('1.5602200465E8','(.+)(E)',1),'\\.',''))
> el '1.5602200465E8'
> end
不动产> from dual;
OK
156022004.65
当然这种⽅法最好是封装到UDF中,显得更为简洁,代码可读性也更强