我在excel中有以下一组计算,我希望能够在存储过程中使用。
Excel中
CellA: 45/448.2 = 0.100401606425703
CellB: 1-CellA = 0.899598393574297
CellC: 1-CellB = 0.100401606425703
CellD: CellC * 448.2 = 45.000000000000000
在SQL中,我正在执行以下操作:
declare @a decimal(18,15) = 45/448.2
declare @b decimal(18,15) = 1-@a
declare @c decimal(18,15) = 1-@b
declare @d decimal(18,15) = @c * 448.2
我也试过在一行中运行计算
declare @e decimal(18,15) = (1-(1-(45/448.2)))*448.2
当我返回值时,SQL给出了以下内容:
@a: 0.100401000000000
@b: 0.899599000000000
@c: 0.100401000000000
@d: 44.999728200000000
@e: 44.999728200000000
我已经尝试在SQL中调整小数的精度,但我没有什么区别,它只返回小数的前6位数。
Excel在运行公式时是否进行任何优化?
有什么想法吗?
答案 0 :(得分:7)
即使只是你的第一行足以显示问题:
declare @a decimal(18,15) = 45/448.2
print @a
给出
---------------------------------------
0.100401000000000
这是因为数据类型。当你说
448.2
它是(每the documentation)被解释为 decimal
类型的常量,also per the documentation,
在Transact-SQL语句中,带小数点的常量是 使用最小值自动转换为数字数据值 精度和规模必要。例如,常数12.345是 转换为精度为5且比例为3的数值。
所以448.2
是decimal(4,3)
。 45
integer
,与decimal
is treated as having precision of 10 and scale 0结合使用时。当我们分开时,the rules说
Operation Result precision Result scale
e1 / e2 p1 - s1 + s2 + max(6, s1 + p2 + 1) max(6, s1 + p2 + 1)
在这种情况下,结果精确度为10 - 3 + 0 + max(6, 0 + 3 + 1)
,缩放为max(6, 0 + 3 + 1)
,结果为13
和6
。
6
的结果范围是结果只有六位小数的原因。
解决问题的方法是在操作之前将操作数设置为适当的类型;例如,这里有两种方式:
强制将某个数字视为浮点数:
declare @a decimal(18,15) = 45/448.2e0
select @a
---------------------------------------
0.100401606425703
明确提供小数位:
declare @a decimal(18,15) = 45/cast(448.2 as decimal(18,10))
select @a
---------------------------------------
0.100401606425703