SQL Server两值除法结果异常问题求助
解决SQL Server整数除法导致结果不符的问题
嘿,我来帮你搞定这个困惑!你遇到的问题其实是SQL Server里整数除法的默认行为在搞鬼,新手很容易踩这个坑。
问题根源
SQL Server中,如果两个整数类型的数值相除,它会自动执行整数除法——也就是直接截断小数部分,只返回整数结果,完全不会四舍五入。比如你手动算的是9.52,但如果你的Sum(DATEDIFF...)和Count(IdPiece)都是整数,直接相除就会丢掉小数,甚至如果分子分母的顺序不符合你的预期,结果会差得更远。
看你的情况:你得到的整数除法结果是21,加了1.0 *后得到22.68,这说明你的Sum结果(NbJours)远大于Count结果(NbPiece),但你期望的是9.52,大概率是你把分子分母的顺序搞反了——比如你实际想算的是Count(IdPiece) / Sum(...),而不是现在的Sum(...) / Count(...)。
解决方案
1. 先修正除法的精度问题
要得到带小数的正确结果,你需要把其中一个操作数转换为浮点型,强制SQL Server执行浮点除法,有几种常用方式:
- 用
1.0 *乘以其中一个数,最简单直接:SELECT Count(IdPiece) AS NbPiece, Sum(DATEDIFF(day, CONVERT(DATETIME,Ecriture.DateComptable,103),CONVERT(DATETIME,Ecriture.DateCreation,103))) as NbJours, -- 用1.0乘以分子,强制转为浮点运算 1.0 * Sum(DATEDIFF(day,CONVERT(DATETIME,Ecriture.DateComptable,103),CONVERT(DATETIME,Ecriture.DateCreation,103))) / Count(IdPiece) AS Moy_Saisie2 FROM Ecriture; -- 别忘了补充你的表名 - 用
CAST或CONVERT明确转换类型,更严谨:
这里用SELECT Count(IdPiece) AS NbPiece, Sum(DATEDIFF(day, CONVERT(DATETIME,Ecriture.DateComptable,103),CONVERT(DATETIME,Ecriture.DateCreation,103))) as NbJours, CAST(Sum(DATEDIFF(day,CONVERT(DATETIME,Ecriture.DateComptable,103),CONVERT(DATETIME,Ecriture.DateCreation,103))) AS DECIMAL(10,2)) / CAST(Count(IdPiece) AS DECIMAL(10,2)) AS Moy_Saisie2 FROM Ecriture;DECIMAL(10,2)可以指定保留两位小数,结果更精准。
2. 检查分子分母的顺序
如果你期望的结果是9.52,那当前的Sum/Count得到22.68显然不符合,所以你应该调换分子分母的顺序,改成Count/Sum:
SELECT Count(IdPiece) AS NbPiece, Sum(DATEDIFF(day, CONVERT(DATETIME,Ecriture.DateComptable,103),CONVERT(DATETIME,Ecriture.DateCreation,103))) as NbJours, -- 调换顺序,用1.0强制浮点运算 1.0 * Count(IdPiece) / Sum(DATEDIFF(day,CONVERT(DATETIME,Ecriture.DateComptable,103),CONVERT(DATETIME,Ecriture.DateCreation,103))) AS Moy_Saisie2 FROM Ecriture;
这样如果你的NbPiece是200,NbJours是21,结果就会是200/21≈9.52,正好符合你的预期。
总结
先确认你的业务逻辑是要计算“总天数/总件数”还是“总件数/总天数”,然后通过转换操作数类型避免整数除法,就能得到正确的带小数结果啦!
内容的提问来源于stack exchange,提问作者MaximeV




