我在hue中运行一个hive表的sum函数,得到一个返回值nan。
这是我的密码: select sum(v1) from hivedb.tb1;
我不知道为什么它会给我一个结果。我检查了我的v1值是否为空: select * from hivedb.tb1 where v1 is null;
,结果没有记录具有空值。这个表有1亿行,所以我不能手动检查每条记录。
有人知道我为什么得到一个结果吗?
如果是因为我在某些行中有一些异常值,我怎么能找到它们呢?
感谢您的帮助。提前谢谢!
update1我手动筛选了前1000行,幸运的是在tb1中发现了一些异常的nan值。这是由于前面步骤中的一些舍入误差造成的。所以我的问题1可能已经回答了。如果您认为还有其他原因,请随时发表评论。
我仍然不知道如何使用一种有效的方法来发现具有nan值的行。所以我仍然期待着我的问题2的任何答案。请随意分享。我感谢你的帮助。
更新2在下面的讨论部分中,在接受答案的帮助下,问题得以解决。有多种方法可以解决这个问题。
使用条件选择v1+1>v1。它将选择具有非nan值的行。
使用条件选择cast(v1 as string)=“nan”。它将选择具有nan值的行。
2条答案
按热度按时间qc6wkl3g1#
你可以把nan当作
v1l68za42#
hive依赖于java(加上针对null和friends的sql特定语义),java遵守ieee数字语义标准。也就是说。。。南很狡猾。
引用那篇文章。。。
(Float.NaN == Float.NaN)
总是返回false。事实上,如果您看看
Float.isNaN()
,如果一个数不等于它自己,它就不是一个数(这是有意义的,因为一个数应该等于它自己)。对double.nan也一样
因此,向您展示如何使用调用的(未记录的)配置单元函数是没有意义的
reflect2
,它允许您在配置单元列上调用原始java方法,即。……因为——理论上——你可以简单地说:
免责声明——我见过这样的情况:配置单元优化器进行了激进的“优化”,并产生了错误的结果。
换句话说,如果
v1=v1
子句没有按预期筛选出nan值,然后查看reflect2
...编辑——实际上,优化器似乎忽略了
v1=v1
在某些版本的配置单元中使用子句(请参阅注解),因此需要一个更离经叛道的公式:v1 +1.0 > v1
应该有用。。。除非舍入误差abs(v1)
<<1或abs(v1)
>> 1其他“数字”技巧在边缘情况下也会失败,尤其是在
v1 =0.0
最后,最稳健的方法似乎在尝试cast(v1 as String) <>'NaN'
(因为所有可能的nan值都显示为“nan”,即使它们在算术意义上不是严格的“相等”)。关于的旁注
reflect2
--你可以看到,它确实没有提到在官方Hive文件,而reflect
被提及(甚至有一个特定的wiki条目)。但是它早在hive v0.11(参见hive-4025)中就已经实现了edit—java“反射”现在在odbc/jdbc/hue连接的默认情况下被禁用(请参阅注解),并且在使用诸如ranger或sentry之类的安全插件时不能重新启用。因此它的用法仅限于(已弃用)
hive
客户端。