看到这心都凉了,怎么会是null呢????

不可能 绝对不可能 怎么decimal相乘直接就没数据了呢?

先说暂时性补救办法

但是这个到底是怎么发生的呢?

为啥在impala里查询就是好的呢?这个就像一个定时炸弹.....

参考文章

Hive 2.3 decimal精度损失问题 - 简书

他的是精度丢失,而我的直接为null,这不是更可怕么。

突然想到他用explain,发现了问题,那我也看下

截取关键部位。

expressions:

'1458339759464521728' (type: string),

order_amt (type: decimal(38,18)), (order_amt * order_amt) (type: decimal(38,36)), (round(order_amt, 10) * round(order_amt, 10)) (type: decimal(38,20)),

(round(order_amt, 4) * round(order_amt, 4)) (type: decimal(38,8)),

(UDFToString(order_amt) * UDFToString(order_amt)) (type: double)

突然一下就明白了

我们设置的decimal(38,18)乘以decimal(38,18) 为了确保精度不变,变成了decimal(38,36),再仔细看下数据 发现c2就是直接相乘那一列,有的有值有的没有值,有值的整数都只有两位,与结果对应上了。

解决办法如上所示,

一种是通过round(decimal,4)   这样 decimal(38,4)*(38,4)=decimal(38,8) 可以保留30位整数。。

如果你的整数位特别多,可以考虑 cast(decimal as string)*cast(decimal as string) 但是这样的结果会有精度的损失,当然上面的也有...看自己了。。。

________________________________________________________________

下面是CDP hive3.1版本测试

select id,id*id from test_decimal;

 explain formatted  select id,id*id from test_decimal; 截取关键

"expressions:": "id (type: decimal(38,18)), (id * id) (type: decimal(38,6))",

直接保留6位小数了

测试的* 和+

"expressions:": "d1 (type: decimal(38,18)), d2 (type: decimal(38,18)), (d1 * d1) (type: decimal(38,6)), (d2 * d2) (type: decimal(38,6)), (d1 + d1) (type: decimal(38,17)), (d2 + d2) (type: decimal(38,17)), (d1 + d2) (type: decimal(38,17)), (d2 + d1) (type: decimal(38,17))",

乘以直接保留六位小数

加号直接保留十七位小数

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐