2017-08-07 137 views
0

精确值,我将100000 =金额为9 =转移到天= 30如何获得在SQL Server

但是,当我需要的实际金额让我怎么做呢?

在SQL:

Declare @R1 as money, @R2 as money, @R3 as money 

Set @R1 = 100000/9/30 
Set @R2 = @R1 * 9 * 30 

select @R2 As 'ActualAmount' 

我到底需要100,000,但结果是99900.00 - 为什么?

回答

2

默认情况下,SQL会做整数除法。只需添加*1.0使其小数除法

Set @R1=100000*1.0/9/30 

SQL DEMO

使用浮动,而不是钱

SELECT (100000/9/30)*9*30 result, 'v1' as version 
UNION 
SELECT (100000*1.0/9/30)*9*30, 'v2' 
UNION 
SELECT (CAST(100000 as float)/9/30)*9*30, 'v3' 
ORDER BY version 

输出

enter image description here

+0

由于它的作品,但现在是导致100000.008 – hamza

+0

检查更新版本 –

+0

现在是上班100000 .FINE ... SELECT(CAST(100000浮法)/ 9/30)* 9 * 30 V3 – hamza

0

欢迎来到浮点舍入错误的奇妙世界。 100000/9 = 11111.1111...重复。让我们简化示例并假装我们只想要10/3;不同的功能,同样的问题。当10/3表示为一小部分,你可以做(10/3) * 3,抵消了三分球,并取回10.但是一个电脑卖场10/33.33333...重复,拿出来作为高精密,因为它可以得到的。这种精确度实际上是一个有点复杂的问题,但可以说,这不是无限的。所以实际存储的是类似于3.333333....0。当你乘以3时,计算机会说“啊,你让我乘3.3333 ... 0 * 3,这当然是9.99999 ... 0”。

数学,你期望得到10回(或你的情况,100,000)是完全合理的。但由于如何与循环小数电脑卖场数字,电脑不认有10/33.33333...(之间的等价其实,它像是做,但它的原因可能更多地与运气,以后会更多)。

正如有人指出,在另一个答案,你得到99900的原因是因为它做整数除法,而不是浮点除法。那么这个问题就变成了什么你投了100000以获得你想要的答案?

在你的情况,似乎float得到它的权利,但值得注意的是,这可能不是在所有情况下的情况。这可能证明正确的,因为浮动有53个在其尾数提供小数位(显著位),并用精密该水平,SQL使一个受过教育的猜测,你是,事实上,试图重新形成一个具有无限重复小数分数而不是将三个数字相乘得非常接近,但并不完全等于原始数字。

Money另一方面通常是一个不好的选择作为数据类型,因为它实际上只是一个小的精度float并导致这样的问题。 Decimal也有在这种情况下一些问题,因为它实际上重新形成的价值。

declare 
    @Money money = cast(100000 as money)/2700, 
    @Float float = cast(100000 as float)/2700, 
    @Decimal decimal(38,2) = cast(100000 as decimal(38, 2))/2700 

select 
    _Money = @Money, 
    _MoneyReformed = @Money * 2700, 
    _Float = @Float, 
    _FloatReformed = @Float * 2700, 
    _Decimal = @Decimal, 
    _DecimalReformed = @Decimal * 2700 

如果您需要分数的真实,普遍正确的表示,你必须在分子和分母存储在单独的列,因此您可以独立操作每个。