请教hive 里的where 判断——string格式字段用where a>b筛选结果与 where a-b>0筛选结果不一致

fanrenhufan126 2017-09-13 04:07:20
最近遇到hive并表后筛选问题,出现了一个很神奇的错误——string字段用where a>b筛选结果与 where a-b>0筛选结果不一致

1)对于同样为string格式的两个数值字段进行大小比较,因为考虑到hive会隐性转换数据格式,故而直接筛选val1>val2记录,而实际筛选出来的记录中,仍有大量val1<val2的记录,其中有看起来精度一致的,也有看起来精度不一致的,例如val1为2.0、val2为4,或者val1为4.2、val2为3.1。

2)发现问题后,改用val1-val2>0筛选记录,记录无误,符合筛选要求。

3)尝试先对原始字段进行转化,即cast(xx as float),结果正确,与val1-val2>0筛选结果一致。

关键是,两个源头表的所有字段类型都是string。请教各位高人指点,这是什么原因,是我忽略了什么么?

第一轮有问题的原始代码样例
select a.id,
a.val1,
b.val2
a.val1-b.val2
from (select id,val1 from table1) a
left join (select id,val2 from table2 ) b
on a.id=b.id
where a.val1>b.val2;
结果样例:
2.0 3.00004
4.2 5.1

第二轮val1-val2>0筛选代码
select a.id,
a.val1,
b.val2
a.val1-b.val2
from (select id,val1 from table1) a
left join (select id,val2 from table2 ) b
on a.id=b.id
where a.val1-b.val2>0;
结果无误
cast结果同第二轮结果
...全文
1136 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
碧水幽幽泉 2017-09-18
  • 打赏
  • 举报
回复
说一个关于"复盘"的工作方法:
趁着记忆还是热腾腾的,赶紧复盘,把重要的经验教训梳理沉淀下来,是做一事有一事进益的好法门。

在此记之以提醒和勉励自己。
还记得第一次帮公司引进PE,前后历时9个多月,引入资金1个亿左右。事情宣布告一段落,领导催促我:赶紧把这整个引资的过程梳理一遍,交一份报告和心得上来。
于是我把整个过程的时间表、心得体会、结案报告和整个过程的文档打了个包发给领导,并在他的要求之外做了更多,把各个节点的“Why”进一步弄清楚——比如涉及框架协议、投资协议,
就把桂曙光的《Term Sheet条款详解》系统消化后压缩成概要版的科普小报告存了下来。
这件事情的作用很大,使得我对整个过程掌握得很清楚,再遇到类似的事情时完全可以以熟手的身份出现;
别人咨询相关事宜的时候,能随口说出应该如何做,及为什么这么做,因此展示出很好的专业性。
后来组织开上市公司董事会会议的时候,也充分用了“复盘”这种方法——第一次组织董事会会议时,小的纰漏不少。
于是会后和项目小组成员你一言我一语地把整个过程拼凑完整,并把所有环节的时间、地点、角色、事务、物资、信息传递等方面抠细——精确到打印纸是用哪一个牌子。
而第二次组织开会的时候,带着一群新手,自己确基本不用费多少力气,对着上次梳理的操作指引,就可以把整个会开得行云流水不犯一点错误。
此后不管是做上市前股权激励,还是IPO,都做了这项工作,受益很多。
小结如何复盘:
1、梳理出做整件事情的流程图;
2、先抓要点,把影响事情走向的关键节点标识出来;
3、各个节点涉及的方案和选择的原因是什么弄清楚;
4、根据流程图把整个过程的任务表拆细(WBS);
5、梳理出一张易错事宜的备忘清单;
6、把标准的定稿文档、起支持作用的资料规范命名并建档保存。
碧水幽幽泉 2017-09-18
  • 打赏
  • 举报
回复
成功人士的3个好习惯:
1.学会做人
2.相信自己
成功人士不管是在自己的内心世界,还是在公众面前都是充满信心的,成功学的严爵出国表明:
成功的与床是创造和拥有财富的源泉。没有信心,不相信自己的人,那是不可能成事的。
3.目标明确

一个人是否能够成功,职业上的天赋只是一部分,情商的高低对一个人的成功起着决定性的作用。
情商主要指人在情绪、情感、意志乃至承受挫折等方面的品质。想要获得成功,就要比别人多付出几倍甚至更多的努力。

"成功不在一时,而在一世", 这是他的座右铭。成功中的快乐与痛苦是辩证的关系,一个顶尖人才在人前有多辉煌,他背后就要承受多大的痛苦。

不论是谁,想要赢得成功,必须做到持之以恒的坚持与付出,除此之外,别无他途。

一般情况下,人人都渴望获得成功,但有很多人却从不思考成功因何而来?天上不会无缘无故掉馅饼,成功也不是无缘无故就会降临到某人头上的,那种"巧中500万"的事此处省略不谈。
众所周知,成功从奋斗中来,而奋斗又必须仰仗一个人优秀的习惯和孜孜不倦的坚持。简单点说,坚持30天去做同一件事情,培养一个好习惯,从来都不是很难的事。
只要每天投入一点时间和精力,就能看到成果。《坚持,一种可以养成的习惯》已经教会了我们如何去培养一项习惯,如何坚持去做自己喜欢的事情。
那么,亲爱的朋友,你还有什么可迷茫的呢?很简单,现在就投入到自己的生活中去,开始坚持做一件自己喜欢的事情,把它培养成习惯,镶嵌到生命的骨缝里。
我坚信,如果你能坚持一年、三年、五年、十年,你的人生必定是另一幅灿然有光的面貌,丰盛而富美,令众人羡慕。
但在投入一项习惯之前,一定记住两件事:1.每天坚持行动。2.坚持到底。
碧水幽幽泉 2017-09-18
  • 打赏
  • 举报
回复
Hive常见问题总结:
1.分隔符
创建普通的表:create table test_table (id int,name string,no int) row format delimited fields terminated by ',' stored as textfile;
//指定了字段的分隔符为逗号,所以load数据的时候,load的文本也要为逗号,否则加载后为NULL。hive只支持单个字符的分隔符,hive默认的分隔符是\001

2.加载表
load data local inpath '/home/zhangxin/hive/test_hive.txt' overwrite into table test_part partition (dt='2012-03-05');
//local是本地文件,注意不是你电脑上的文件,是hadoop所在的本地文件
//如果是在hdfs里的文件,则不需要local。 overwrite into是覆盖表分区,仅仅是这个分区的数据内容,如果是追加,则不需要overwrite

3.复制表结构
创建与已知表相同结构的表:只复制表的结构,而不复制表的内容。
create table table2 like table1;

4.Limit可以限制查询的记录数
select * from test limit 5; --查询5条数据
select * from test sort by amount desc limit 5; --查询金额最大的5条数据

5.Hive不支持的地方
5.1不支持EXIST ,NOT EXIST
5.2不支持所有非等值的连接(支持等连接和外连接),因为非等值连接非常难转化到 map/reduce任务
5.3不支持UPDATE, DELETE操作
5.4不适合用于联机online)事务处理,也不提供实时查询功能。
Hive中由于没有索引,需要扫描整个表,因此延迟较高。Hive不适合在线数据查询。
由于Hive建立在集群上并可以利用 MapReduce 进行并行计算,因此可以支持很大规模的数据
5.5不支持having
5.6不支持窗口函数
5.7不允许在同一个查询内有多个distinct 表达式。


6.导出查询结果到指定目录
将查询数据输出至目录:
insert overwrite directory '/tmp/hdfs_out' select a.* from table_name a where a.dt='${date}';

将查询结果输出至本地目录:
insert overwrite local directory '/tmp/local_out' select a.* from table_name a;

7.left semi join
select * from table1 left semi join table2 on (table1.id=table2.id);
相当于"select * from table1 where table1.id in (table2.id)" --相当于inner join

8.修改表结构
显示所有表:show tables;
模糊查询表: show tables '*字符串*'

修改表名: alter table table_name rename to new_table_name
表添加一列:alter table table_name add columns (new_col int);
添加一列并增加列字段注释: alter table table_name add columns (new_col int comment 'a comment');
更新列:alter table table_name replace columns (col_name data_type [comment col_comment], ...) --replace表示替换表中所有字段。

修改列的名字/类型/位置/注释:
alter table table_name change [column] col_old_name col_new_name column_type [comment col_comment] [first|after column_name]

获取建表语句: show create table table_name
删除表: drop table [if exists] table_name

9.使用Hive执行hive命令输出到本地文件
hive -e "select * from test1222;" > test.txt

10.hive 默认的字段分隔符为ascii码的控制符\001,建表的时候用fields terminated by '\001'
如果要测试的话,造数据在vi打开文件里面,用ctrl+v然后再ctrl+a可以输入这个控制符\001。按顺序\002的输入方式为ctrl+v,ctrl+b。

11.中文别名应加上反印号(反印号在ESC键下面)
select 1001 as `代码` from dual;

12.什么是MapReduce
概念"Map(映射)"和"Reduce(化简)"

13.删除部分数据和清空数据:
删除部分数据: insert overwrite table table_name select * from table_name where 条件;
清空表数据: insert overwrite table table_name select * from table_name where 1 = 0;
truncate table table_name
truncate table table_name partition (dt='日期');

14.Hive 的数据存储
首先,Hive没有专门的数据存储格式,也没有为数据建立索引,用户可以非常自由的组织 Hive 中的表,
只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据。
其次,Hive中所有的数据都存储在HDFS中,Hive中包含以下数据模型:Table,External Table,Partition,Bucket。
Hive中的Table和数据库中的 Table 在概念上是类似的,每一个 Table 在 Hive 中都有一个相应的目录存储数据
例如,一个表 pvs,它在 HDFS 中的路径为:/wh/pvs,其中,wh 是在hive-site.xml 中由 ${hive.metastore.warehouse.dir} 指定的数据仓库的目录,
所有的 Table 数据(不包括 External Table)都保存在这个目录中。

15.CLI
$HIVE_HOME/bin/hive是一个shell工具,它可以用来运行于交互或批处理方式配置单元查询。

16.DROP
删除一个内部表的同时会同时删除表的元数据和数据。删除一个外部表,只删除元数据而保留数据。

17.如何查看当前的hive的版本
方法1: hive> set hive.hwi.war.file;
方法2: 找到hive所在目录,然后查看jar包的版本号,

20,809

社区成员

发帖
与我相关
我的任务
社区描述
Hadoop生态大数据交流社区,致力于有Hadoop,hive,Spark,Hbase,Flink,ClickHouse,Kafka,数据仓库,大数据集群运维技术分享和交流等。致力于收集优质的博客
社区管理员
  • 分布式计算/Hadoop社区
  • 涤生大数据
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧