MySQL对查询的值四舍五入保留两位小数的方法
前言
开发财务、充值、消费、余额相关业务时,经常遇到金额展示需求:数据库原始小数位数较多,前端需要统一保留两位小数展示。
很多同学习惯把原始数值查询出来,在 Python / Java 代码里做四舍五入处理。
实际上 MySQL 原生提供数值函数,可以直接在SQL层面完成四舍五入。
本文重点讲解 ROUND() 函数,区分容易混淆的 TRUNCATE()、FORMAT(),同时梳理财务场景踩坑点、NULL空值兼容方案,给出现成可直接复制的业务模板。
一、核心函数:ROUND() 四舍五入
语法
ROUND(数值, 保留小数位数)
- 规则:四舍五入
- 返回类型:数值类型,可以继续参与加减运算
基础示例
SELECT ROUND(123.456, 2); -- 123.46 SELECT ROUND(123.454, 2); -- 123.45 SELECT ROUND(100, 2); -- 100.00
结合聚合函数 SUM()(业务最常用)
统计充值、余额、消费金额场景:
-- 当日充值总额,求和后四舍五入保留2位 SELECT ROUND(SUM(money), 2) AS day_recharge FROM sys_recharge_log WHERE create_time >= CURDATE() AND create_time < CURDATE() + INTERVAL 1 DAY;
二、重要配套:兼容NULL空值 IFNULL
一个高频坑:当查询没有匹配数据时,SUM() 结果为 NULL,ROUND(NULL,2) 依旧返回NULL。
程序如果直接使用会出现空值报错。
解决方案:IFNULL() 兜底,不存在数据时返回 0.00。
标准生产写法:
SELECT IFNULL(ROUND(SUM(money), 2), 0.00) AS day_recharge FROM sys_recharge_log WHERE create_time >= CURDATE() AND create_time < CURDATE() + INTERVAL 1 DAY;
逻辑说明:
- 先执行 SUM 求和
- 求和结果传入ROUND四舍五入
- 如果整体结果为NULL,替换为 0.00
三、容易混淆的两个函数,不要用错
1. TRUNCATE() 直接截断,不四舍五入
SELECT TRUNCATE(123.459, 2); -- 123.45
适用场景:只想要舍弃后面小数、不进位;财务金额统计严禁使用,会造成金额误差。
2. FORMAT() 格式化(谨慎使用)
SELECT FORMAT(IFNULL(ROUND(SUM(money),2),0), 2);
特性:
- 自动增加千分位逗号
1,234.56 - 返回字符串类型
⚠️重大风险:
拿到结果后如果继续做数值加减运算,极易引发类型异常;
只适合直接前端展示,不适合后续参与计算。
总结区分:
✅ 金额统计、后续还要运算:ROUND + IFNULL
❌ 财务计算不要用 TRUNCATE
❌ 需要二次运算不要使用 FORMAT
四、实战多字段横向汇总场景
仪表盘统计多条金额指标,一次性统一处理小数:
SELECT
IFNULL(ROUND(SUM(CASE WHEN type=1 THEN money ELSE 0 END),2),0.00) AS money1,
IFNULL(ROUND(SUM(CASE WHEN type=2 THEN money ELSE 0 END),2),0.00) AS money2,
IFNULL(ROUND(SUM(price),2),0.00) AS consume
FROM sys_balance
WHERE expire_time >= NOW() AND status = 1 AND user_id = 'xxx';
五、两种实现方案对比:SQL处理 VS 应用代码处理
方案A:SQL内部 ROUND 处理(推荐)
优点:
- 统一规则,前后端不需要重复维护保留小数逻辑;
- 减少应用层判空、类型转换代码;
- 多条统计汇总时代码更简洁。
缺点:
复杂计算逻辑全部压在数据库,极端大量并发场景需要评估压力。
方案B:原始数值查出,Python/Java代码四舍五入
优点:灵活,可以针对不同场景切换保留位数;
缺点:
- 每个接口都要重复写格式化逻辑,容易漏写;
- 多人开发容易出现标准不统一,有的四舍五入、有的直接截断。
建议规范:单纯展示类报表、后台统计页面,优先SQL层统一ROUND。
六、高频开发踩坑清单
坑1:函数顺序写反
❌ 错误写法
ROUND(IFNULL(SUM(money),0.00), 2)
逻辑没问题,但推荐下面可读性更强顺序;
✅ 推荐顺序
IFNULL(ROUND(SUM(money), 2), 0.00)
坑2:忘记处理NULL,程序拿到None
没有业务数据时 SUM 返回 NULL,前端展示出现空白。务必搭配 IFNULL。
坑3:使用FORMAT接收后继续运算
# 危险!FORMAT返回带逗号的字符串,转float报错 row['day_recharge'] = "1,200.50" float(row['day_recharge']) # 转换异常
坑4:金额字段使用float存储
浮点类型本身存在精度丢失,最佳实践:金额使用 DECIMAL(18,2) 存储,从根源避免精度问题。
七、编码规范模板(直接复制使用)
单条金额统计标准模板
SELECT IFNULL(ROUND(SUM(money), 2), 0.00) AS num FROM sys_recharge_log WHERE create_time >= CURDATE() AND create_time < CURDATE() + INTERVAL 1 DAY AND type = 1;
分组统计场景
SELECT
type,
IFNULL(ROUND(SUM(money), 2), 0.00) AS total_money
FROM sys_balance
WHERE status = 1
GROUP BY type;
八、全文总结
- 四舍五入优先使用 ROUND(数值,2),返回数值,支持后续运算;
- 无匹配数据会产生NULL,固定搭配
IFNULL(...,0.00)兜底; - TRUNCATE 截断不进位,财务业务禁止随意使用;
- FORMAT生成带千分位字符串,仅用于直接展示,不要参与数值计算;
- 报表类金额统计建议在SQL层统一处理小数规则,避免应用代码各处重复格式化;
- 存储金额尽量使用 DECIMAL 类型,规避浮点数精度丢失隐患。
财务数据对精度敏感,统一SQL层使用ROUND规范处理,能极大减少前后端因小数保留规则不一致产生的对账问题。
以上就是MySQL对查询的值四舍五入保留两位小数的方法的详细内容,更多关于MySQL查询值保留两位小数的资料请关注脚本之家其它相关文章!


最新评论