【已解决】MySQL:常用的除法运算+精度处理+除数为0处理

目录

问题现象:

问题分析:

拓展:

1、除法运算:

拓展:MySQL中常用的几种除法运算

        1、取整除法

        2、浮点数除法

        3、取余除法

        4、向上取整除法

        5、向下取整除法

2、运算结果的精度处理

        1.1、浮点数

        1.2、总位数

        1.3、小数点后几位数

总结:

拓展:不要滥用cast句式

3、除数为0的处理

        3.1、在程序中处理

        3.2、sql中赋值为0

解决方法:


问题现象:

        今天在项目中遇到一个需求是需要开发一个用到数据统计的接口,那么就有可能需要使用sql语句来进行除法运算;那么如何解决mysql中除法运算的以下2个问题呢:

        1、运算结果的精度处理;

        2、除数为0的处理。


问题分析:

        首先,在进行数据统计相关的开发时,一般都会采用接口开发定时任务统计这两种情况;而数据的统计逻辑一般有两种方式:

        1、在数据库中进行简单运算,并将运算结果集返回给后端的dao层接口;

        2、从数据库获取数据,然后在后端程序中做数据统计逻辑;

        如果是简单的运算的话,可以采用第1种方式;而如果是需要进行大量复杂运算的话,建议采用第2种方式,如果你不确定的话也使用第2种方式,因为程序中可以很方便地实现简单运算,能完全兼容第1种方式,优点是可以定义各种变量来存储运算中的过程值;而第1种方式则适用于输出简单的运算结果。


拓展:

        当然,我们都知道在数据库中,其实也可以使用存储过程(可以理解为后端服务中的函数\方法),来实现类似于后端程序的复杂运算逻辑,但是使用存储过程比使用后端程序的效率要低,所以不建议使用数据库的存储过程代替后端程序的方式来实现数据统计逻辑。


       由于我这里需要做的是简单的除法运算,因此我想采用第1种方式来实现,那么现在就来分析一下文章开头提出了两个问题:

1、除法运算:

        MySQL中作除法运算有很多种,其中最简单且常用的就是直接使用除法运算符(/);这种除法的特点是:运算结果是个浮点数。

        例如:

select 10/5;
-- 结果:
-- 2.0000select 10/6;
-- 结果:
-- 1.6667

        可以发现:这种除法运算的默认规则就是:

        小数点后保留4位数,且采用四舍五入的规则。


拓展:MySQL中常用的几种除法运算

        MySQL中的除法运算有以下几种:

        1、取整除法

MySQL旧版本:
DIV(被除数, 除数)MySQL新版本:
被除数 DIV 除数

        这里需要注意的一点是:上面列出了在MySQL中新旧版本下的DIV句式的使用规则,如果版本不对就会报错,这里由于我用的版本是MySQL8+,算是新版本,所以旧版本的句式不适用,所以就会报错如下:

        所以如果报错的话,就换另一种句式试试吧。这里我只测试MySQL8+下成功的句式规则:             例如:

        2、浮点数除法

        运算结果是浮点数格式,默认是小数点后保留4位数,且采用四舍五入的规则。

        例如:

        3、取余除法

        取运算结果的余数,也就是在除不净时余下的数值。

        例如:

        4、向上取整除法

        得出运算结果后,先取整数部分;然后如果小数部分数值 > 0,则整数部分+1作为最终返回的结果。

        例如,10/3=3.333...3;由于结果是个处于整数3和整数4之间的浮点数,所以向上取整,结果为:4。

        5、向下取整除法

        得出运算结果后,取整数部分。

        例如,10/3=3.333...3;由于结果是个处于整数3和整数4之间的浮点数,所以向下取整,结果为:3。


2、运算结果的精度处理

        在mysql中可以使用以下句式来控制一个浮点数的精度:

cast(浮点数 AS DECIMAL(总位数, 小数点后几位数))

        这个句式需要用到3个参数:

        1.1、浮点数

        传入你想要操作的浮点数数据,在select...from语句中可以指定某个表的字段。

        1.2、总位数

        总位数指的是运算结果(浮点数)的总位数,分为两部分:小数点后数值的位数之和,所以总位数=小数点前数值的位数+小数点后数值的位数,这个总位数一定要设置的大一些,否则很容易踩坑的,后面我会提到。

        1.3、小数点后几位数

        对于运算结果,设置保留小数点后的几位数,也就是数学中常说的精确到小数点后几位数(精度)。

总结:

        这个句式理解起来和用起来都很简单,唯一需要注意的点就是总位数的设置,这个数据必须设置大一些,尽量靠近数据的上限长度(浮点数的总位数最大值),我一般会设置30。

        如果总位数设置太小,会导致数据失真,容易导致严重的数据问题。

        例子:

select cast(1234567890.1234567890 AS DECIMAL(30, 4));
-- 结果:
-- 1234567890.1235select cast(1234567890.1234567890 AS DECIMAL(14, 4));
-- 结果:
-- 1234567890.1235select cast(1234567890.1234567890 AS DECIMAL(10, 4));
-- 结果:
-- 999999.9999select cast(1234567890.12 AS DECIMAL(10, 4));
-- 结果:
-- 999999.9999

        通过观察上面这4个sql语句的执行结果,不难看出,当总位数 < 浮点数的总位数最大值时,数据就会出现“失真”现象,即:

        浮点数 > 总位数所能容纳的最大浮点数值,此时会直接返回该规则下的最大值,所以就能看到后面两个sql返回的结果是10个9(小数点后4个+小数点前6个);规则是首先满足小数点后有4位数,然后再从小数点往前取6位数,来凑够10位数字,以达到我们设置的总位数。


拓展:不要滥用cast句式

        这里有一个需要注意的点,就是不要滥用cast句式,我们只需要对最终的运算结果做精度设置即可,千万不要画蛇添足地给被除数和除数都做精度设置,否则就会出现以下这种情况:

        可以发现,我们给被除数和除数都设置了精度时,会把两个精度相加【(5,4)+(5,4)=(10,8)】作为运算结果的精度。我们可以分析一下这个结果是怎么得出来的:

第一步先执行:

得出真正的被除数:9.9999

第二步执行:

得出真正的被除数:1.0000

第三步把两个精度加起来作为最终结果的精度规则并做除法运算,相当于:

        而正确的sql应该是:

        由于总位数不够设置太小,导致失真,所以需要增大总位数:


3、除数为0的处理

        我们都知道,在除法运算中除数不能为0;

        但神奇的是:在MySQL中使用到除数为0的除法运算,是不会报错,但是返回的运算结果是Null;

        那么如果除数为Null呢?

        还是没报错,但返回的运算结果还是Null;

        但做过数据统计的小伙伴应该都知道:统计数据的报表中不会显示为null,而需要显示为0、0.0、0%等等,因此当除数为0时,这里提供有两种处理方法:

        3.1、在程序中处理

        当数据库返回的运算结果为null,程序中判断后即可对其做针对性处理,如报错,或者赋值为0等等。

        3.2、sql中赋值为0

        在MySQL中使用IFULLl句式进行处理,返回运算结果0,如下:


解决方法:

        除法运算精度和除数为0的综合处理:

        先设置精度,再处理0:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/285598.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑哥的励志创业路:蹭别人的电脑做抖店

我是王路飞。 没有一步到位的创业项目&#xff0c;也没有一击必中的解决方法&#xff0c;有的只是需要时刻解决的当下问题。 做事/创业/成长/生活/人生&#xff0c;都不要追求百分百的圆满&#xff0c;不要抱有一帆风顺的幻想&#xff0c;不要期待十全十美的结果。 它们的第…

Visual Studio QT6 工程引入组件模块,例如:QtXml

QT 工程引入 QtXml QT 版本 6.6.1 Visual Studio 版本 Microsoft Visual Studio Community 2022 (64 位) - Current 版本 17.7.5 打开 Visual Studio 项目工程选择 工具栏 - 扩展 - QT VS Tools -Qt Project Settings 勾选 xml 后点击确定 点击应用即可 注意&#xff1a;配置环…

day44 动态规划part6

完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 完全背包和01背包问题唯一不同…

外部普米集中监控多个Prometheus实例:Prometheus Agent 模式与Prometheus 联邦模式 超级详细

外部普米集中监控多个Prometheus实例 Prometheus Agent 模式-使用推送方式来监控1.外部Prometheus配置1.需要开放端口&#xff0c;在启动时&#xff0c;需要配置开放监听端口2.添加prometheus启动参数3.修改配置后重启prometheus即可 2.各个节点的普米配置1.修改prometheus.yml…

HiveSQL一本通 - 案例实操

文章目录 0.HiveSQL一本通使用说明6.综合案例练习之基础查询6.1 环境准备创建数据表数据准备加载数据 6.2 简单查询练习1.查询姓名中带“山”的学生名单2.查询姓“王”老师的个数3.检索课程编号为“04”且分数小于60的学生的分数信息&#xff0c;结果按分数降序排列4.查询数学成…

vue.js——学习计划表

1&#xff09;准备工作 ①打开D:\vue\chapter02\ learning_schedule 目录&#xff0c;找到 index.html 文件。 在文件中引 入BootStrap 样式文件&#xff0c;具体代码如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&qu…

【Linux】权限管理

文章目录 前言1.权限访问者的分类2.文件类型与访问权限3.文件权限值的表达方式4.文件访问权限的相关设置5.file指令6.目录权限理解与漏洞7.粘滞位的理解 前言 Linux下有两种用户&#xff1a;超级用户(root)和普通用户 超级用户&#xff1a;可以再linux系统下做任何事情&#x…

Vue3 + Vite + TS + Element-Plus + Pinia项目(3)--新建路由

1、在src文件夹下新建router文件夹后&#xff0c;创建index.ts文件 2、具体如下 import { createRouter, createWebHashHistory } from vue-routerconst router createRouter({history: createWebHashHistory(),routes: [{path: "/index",component: () > impor…

关于YOLOv9项目中使用已有模块自由改进的教程

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;助力高效涨点&#xff01;&#xff01;&#xff01; 1. 文件说明 在YOLOv5-v9&#xff0c;模型的结构是以yaml文件的存储。我们可以在原有的yaml基础上增、减、改模块&#xff0c;创作我们自己的模型。 …

ASM四部曲之一:什么是ASM

文章目录 前言什么是.class文件什么是ASM概述作用域模型基于ASM的程序架构 ASM库结构 前言 本文翻译自ASM官方文档。 什么是.class文件 Java字节码文件&#xff08;.class&#xff09;是Java编译器编译Java源文件&#xff08;.java&#xff09;产生的目标文件。它是一种8位字…

基于SpringBoot+Layui的社区物业管理系统

项目介绍 社区物业管理系统是基于java程序开发,本系统分为业主和管理员两个角色 业主可以登陆系统,查看车位费用信息,查看物业费用信息,在线投诉,查看投诉,在线报修; 管理员可以车位收费信息,物业收费信息,投诉信息,楼宇信息,房屋信息,业主信息,车位信息,抄表信…

芯片设计工程师必备基本功——《Verilog+HDL应用程序设计实例精讲》

进入芯片行业需要学习哪些基本功呢&#xff1f;其实芯片设计工程师的技能是通过多年的经验学习的。在您开始作为芯片设计工程师工作之前&#xff0c;很难给出一个需要的全面的单一列表&#xff0c;也不可能学习所有内容。话虽如此&#xff0c;但您开始芯片设计师职业生涯时必须…

瑞萨杯(一)

基础信息 RA6M5&#xff1a;ARM V8架构&#xff0c;24MHz外置晶振&#xff0c;200MHz主频 SCI&#xff08;Serial Communications Interface&#xff09;&#xff0c;意为串行通信接口 参考链接&#xff1a; 【瑞萨RA系列FSP库开发】RASCKeil的环境搭建_瑞萨ra mdk-CSDN博客…

Web安全基础入门+信息收集篇

教程介绍 学习信息收集&#xff0c;针对域名信息,解析信息,网站信息,服务器信息等&#xff1b;学习端口扫描&#xff0c;针对端口进行服务探针,理解服务及端口对应关系&#xff1b;学习WEB扫描&#xff0c;主要针对敏感文件,安全漏洞,子域名信息等&#xff1b;学习信息收集方法…

【webpack】----错误解决【Cannot read properties of undefined (reading ‘tap‘)】

1. 报错场景 安装 webpack-obfuscator 后&#xff0c;进行 js 代码混淆编译的时候报错。 2. 报错截图 3. 错误原因 通常是由于版本不兼容或配置错误引起的。 4. 查询本地 webpack 版本 4.1 查询命令 npm 查询 npm view webpack versionyarn 查询 yarn info webpack ver…

2024年第14届生物医学工程与技术国际会议(ICBET 2024)即将召开!

2024年第14届生物医学工程与技术国际会议&#xff08;ICBET 2024&#xff09;将于2024年6月14日至17日在韩国首尔举行。 会议旨在汇聚来自世界各地的研究人员、工程师、院士和行业专业人士&#xff0c;展示他们在生物医学工程与技术领域的最新研究成果和进展。 会议以“生物医学…

欧拉法和Runge-Kutta(龙格-库塔)方法

Euler方法有各种格式&#xff0c;但其精度最高不超过2阶&#xff0c;一般难以满足实际计算的精度要求。因此&#xff0c;有必要构造精度更高的数值计算公式求解微分方程。Runge-Kutta方法就是一种高精度的经典的解常微分方程的单步方法。 下面是欧拉法例子&#xff1a; 参考链接…

【JavaEE -- 网络初识】

网络初识 1. 局域网和广域网1.1 局域网&#xff08;LAN&#xff09;1.2 广域网WAN 2. 网络通信基础2.1 IP地址2.2 端口号 3. 协议 -- 重点3.1 网络通信协议拆分成多层3.2 TCP/IP 五层网络协议 4. 封装和分用4.1 封装过程4.2 分用过程4.3 网络传输的数据单位 5. 网络编程中的客户…

Java基础-反射

文章目录 1.快速入门1.案例引入2.代码实例3.反射机制原理图 2.反射相关类1.反射获取类的成员代码实例结果 2.反射调用优化1.关闭访问检查2.代码实例 3.Class类1.类图2.基本介绍3.Class类常用方法代码实例结果 4.获取Class类对象代码实例结果 5.哪些类型有Class对象 4.类加载1.基…

学习刷题-13

3.23 hw机试【二叉树】 剑指offer32 剑指 offer32&#xff08;一、二、三&#xff09;_剑指offer 32-CSDN博客 从上到下打印二叉树I 一棵圣诞树记作根节点为 root 的二叉树&#xff0c;节点值为该位置装饰彩灯的颜色编号。请按照从 左 到 右 的顺序返回每一层彩灯编号。 输…