我们先看一下这几个 sql 在 hive 中的返回值:

背景:

在实际 hive 脚本的测试中,常规的一些 sql 和 mysal 类似,那么在测试过程中我们要对使用的每个方法的函数或者引入外部 jar 的一些函数有所了解,解读 sql 含义的时候也需要更加仔细耐心。对于一些比较复杂的 sql 来讲,我们只能进行 sql 的拆解然后对每种类型的数据进行场景覆盖,并且对于输入和输出的结果进行比较,但是对于一些隐藏性的问题,我们还是很难覆盖到的,因此举列子说明一下在对于一些金额或者对于精度要求高的情况下,double 和 decimal 精度差异作为讨论。

select  cast('0.00407' as decimal(18,6) )*2500   --10.175
select  cast('0.00407' as decimal(18,6) )*cast(2500 as  decimal(18,2))  --10.175
select  cast('0.00407' as decimal(18,6) )*cast(2500 as  double)  --10.1749999999999
explain select 200 --返回值类型:int
explain select 200.00 --返回值类型:double
explain select 200*200.00 --返回值类型: double
explain select 200*cast(200.00 as decimal(18,2)) --返回值类型: decimal
explain select 200.00*cast(200.00 as decimal(18,2)) --返回值类型: double

decimal 运算先后导致的精度丢失

select 100/12*6 --50.0
select cast(100 as decimal(18,2))/12*6 --49.999998
select cast(100 as decimal(18,2))/cast(12,decimal(18,2))*cast(6,decimal(18,2)) --49.99998
select cast(100 as decimal(18,2))*6/12 --50

总结

亲爱的小伙伴们,在涉及到金额或者精度要求较为高的场景的时候,特别注意乘法和除法,数据的类型和类型之间的转换问题,此例子就是在下遗漏的一个 BUG,对于这种隐深的问题开发和测试都很难发现,但是这次也是一次累积和更深刻理解一些 hive-sql 的知识。🚀 🚀 🚀 🚀 🚀 🚀 🚀


↙↙↙阅读原文可查看相关链接,并与作者交流