前言


公司数据库部分产品基于Hive进行开发,其中出现一个Bug。Oracle中表t1有个字段类型为decimal(38,0),当Hive这边执行了select Floor(col) from dblink,显示 Floor函数计算的精度太大。但是select Floor(col) from oracle_table 在Oracle这边本身就可以执行,而且Floor的意思是取小于等于的最大整数。

首先介绍一下精度问题:precision和scale

1.数据库中precesion和scale问题


(1)precision:表示有效数字(小数点左右总长度),如果没有指定precision的话,Oracle将使用38作为精度。
(2)scale:表示小数范围(小数点右边长度),scale默认设置为0.  如果为负数,Oracle将把该数字取舍到小数点左边的指定位数。
例如:decimal(3,1),表示范围为99.9 ~ -99.9。
(3)多种情况讨论:
(Mysql和Oracle一样,precision简称p,scale简称s)
  • 情况一:如果插入的数据小数点位数比s大,则对scale+1位置的小数进行四舍五入。当decimal(3,1)为1.15时,自动四舍五入为1.2.
  • 情况二:当一个数的整数部分的长度 > p-s 时,Oracle就会报错
  • 情况三:当s为负数时,Oracle就对小数点左边的s个数字进行舍入。
    • 当decimal(10,-1)为9555.151时,四舍五入至小数点左边第一位,结果为9560
    • 当decimal(10,-2)为9555.151时,四舍五入至小数点左边第二位,结果为9600
    • 当decimal(10,-3)为9555.151时,四舍五入至小数点左边第三位,结果为10000
    • 当decimal(10,-4)为9555.151时,四舍五入至小数点左边第四位,结果为10000
    • 当decimal(10,-5)为9555.151时,四舍五入至小数点左边第四位,结果为0。

2.Hive源码中FloorUDF函数


Hive源码中的思路如下:

(1)首先在GenericUDFFloorCeilBase类中重新计算精度,precision=precision-scale+1

(2)其次在HiveDecimalUtils类中实例化decimal时,会验证precision和scale是否合法

但是这里忽略了致命的问题,因为HiveDecimal.MAX_PRECISION=38,当我定义一个列col类型decimal(38,0),真实数据为1。那么执行select Floor(col) from hive_table,真实数据应该为1,但这里会报错。因为GenericUDFFloorCeilBase重新计算precision=38-0+1=39,在validateParameter中会判断39>HiveDecimal.MAX_PRECISION从而报错

3.修改思路


Floor的意思是取小于等于的最大整数
  • 如果scale>0,precision+1多了
  • 如果scale<0, precision+1多了
  • 如果scale=0. precision+1多了
  • 当precision=scale时,+1有用。比如decimal(1,1)取值0.1,Floor正确结果为0,但0本身就是要占用一位有效数字
  • 当precision<scale。比如decimal(2,3),inceptor这里做了判断创建表时precision不能小于scale
因此在GenericUDFFloorCeilBase,我们只需要判断precision等于scale再决定+1.
precision=precision==scale?precision-scale+1:precision-scale

Hive中Floor函数精度计算问题相关推荐

  1. hive中标准偏差函数stddev()详细讲解

    1.标准偏差概念 标准偏差(Std Dev,Standard Deviation) -统计学名词.一种度量数据分布的分散程度之标准,用以衡量数据值偏离算术平均值的程度.标准偏差越小,这些值偏离平均值就 ...

  2. 使用 Excel 中的函数准确计算周岁年龄

    使用 Excel 中的函数准确计算周岁年龄 首先,统一输入日期的格式为 yyyy/m/d,例如1999/9/9,1999/12/31 使用公式 =DATEDIF(开始日期,结束日期,"以何为 ...

  3. 计算机一级证电子表格函数值怎么算,2017年计算机一级WPS辅导:WPS文字的表格中进行函数公式计算...

    如果我说是在WPS文字文档中的表格能进行函数.公式等计算,不仅要显示在WPS文字中,而且完全不用初少的表格计算插件,还要实现像ET中一样多的公式和函数功能.我是在痴人说梦吗?不,其实WPS Offic ...

  4. Hive中row_number()函数用法详解及示例

    目录 一.Hive 中row_number()函数介绍 二.使用示例 三.总结 四.附录 在Oracle中,我们经常会用到row_number() over(partition by clo1 ord ...

  5. matlab中floor函数,floor函数_怎么在excel中使用floor函数

    floor函数即上取整函数,是计算机C语言中的数学函数,与ceil函数相对应.但是它在excel中却是另一种含义,FLOOR函数是向下舍入为最接近指数基数的倍数,下面小编就教你怎么在excel中使用f ...

  6. hive中explode函数的用法

    hive中explode函数的用法 explode函数是一个炸裂函数他可以做一下转换 将这个表格 +--------------+-----------------------------+ | mo ...

  7. matlab中floor函数的使用(向下取整)

    仅用于记录自己学习过程中遇到的函数 matlab中floor函数,向下取整 一.语法 Y = floor(X) 将X的每个元素舍入为小于或等于该元素的最近整数. Y = floor(t) 将持续时间数 ...

  8. 串的模式匹配——KMP中next函数的计算

    KMP算法相比于朴素的模式匹配算法,其改进之处在于:利用已经得到的"部分匹配"结果将模式串向右"滑动"尽可能远的距离.该算法的关键在于next函数的计算,nex ...

  9. mysql中floor函数的作用是什么?

    需求描述: 最近写mysql程序的时候,使用了floor函数,在此记录下该函数的作用 操作过程: 1.使用floor函数的测试 mysql> select floor(1.23),floor(- ...

最新文章

  1. 禁用software reporter tool.exe 解决CPU高占用率的问题
  2. ARM汇编语言中的程序结构
  3. 【pmcaff】2014年中国移动支付用户报告
  4. 【机器学习】特征工程七种常用方法
  5. WCF进阶:将编码后的字节流压缩传输
  6. C语言 数组排序 – 插入法排序 - C语言零基础入门教程
  7. Could not autowire. No beans of 'xxxx' type found的错误提示
  8. java 调用casperjs_Java程序去调用并执行shell脚本及问题总结(推荐)
  9. jsp页面 字体颜色 白色_CSS 文本字体颜色(CSS color)
  10. Ubuntu安装GoogleTest框架并测试C++代码
  11. mysqlbinlog初识
  12. 【asp.net core 系列】6 实战之 一个项目的完整结构
  13. 最简单易懂的git介绍
  14. 网易微专业python数据分析_网易微专业_Python数据分析师 01 数据思维导论:如何从数据中挖掘价值?...
  15. 一个小练习之taptap功能结构图
  16. GitHub上广受欢迎的下载神器:youtube-dl
  17. Powerpoint高级技巧
  18. MySQL学习(一)
  19. 最新版IDEA设置打开IDEA弹出新窗体
  20. 论文汇网站第三期改版完成

热门文章

  1. Matlab绘制特殊图形------散点图
  2. PHP+SQL考勤系统安全性的设计与实现
  3. React hooks - Ref 使用实例
  4. 控制与决策latex排版解答
  5. windows函数(system)
  6. singleTask 与 taskAffinity 缠绵的那些事
  7. ios 事件穿透的原因和解决方法
  8. go语言比java高级在哪里
  9. Matlab Mobile手机版获取gps数据和加速度信号融合
  10. grequests并发之小试牛刀