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
inrt overwrite local directory '/data/temp/temptxt/wdir27scope' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' lect lon,lat,direc_scope,(ca when
length(regexp_extract(wdir_ratio,'([0-9]+\\.)([0-9]+)(E-*[0-9]+)',2))=0 then wdir_ratio when length(regexp_extract(wdir_ratio,'([0-9]+\\.)([0-9]+)(E[0-9]+)',2))
<=cast(regexp_extract(wdir_ratio,'(E)([0-9]+)',2) as int) then rpad(regexp_replace(regexp_extract(wdir_ratio,'([^E]+)',1),'\\.',''),cast(regexp_extract(wdir_ratio,'(E)([0-9]+)',2) as int)+1,'0') when length(regexp_extract(wdir_ratio,'([0-9]+\\.)([0-9]+)(E[0-9]+)',2))>cast(regexp_extract(wdir_ratio,'(E)([0-9]+)',2) as int) then
concat(substr(regexp_replace(regexp_extract(wdir_ratio,'([^E]+)',1),'\\.',''),1,cast(regexp_extract(wdir_ratio,'(E)([0-9]+)',2) as int)+1),'\.',
substr(regexp_replace(regexp_extract(wdir_ratio,'([^E]+)',1),'\\.',''),cast(regexp_extract(wdir_ratio,'(E)([0-9]+)',2) as int)+2)) when wdir_ratio regexp 'E-' then
concat('0.',repeat('0',cast(regexp_extract(wdir_ratio,'(E)(-)([0-9]+)',3) as int)-1),regexp_replace(regexp_extract(wdir_ratio,'(.+)(E)',1),'\\.','')) el wdir_ratio end) from
wdir27_scope_result4 where direc_scope not is 'error';
宠物狐
品质文化当然这种⽅法最好是封装到UDF中,显得更为简洁,代码可读性也更强