SQL Server 奇怪的 ROUND() 行为

法耶 D。

我有一个巨大的产品行表......我只需要它的一小部分数据,更具体地说是产品的价格(常规价格 - 我必须在两个字段之间进行选择,如果存在的话,我选择它,否则我选择另一个;和销售价格 - 对于许多产品,它存储为三位小数的浮点数,因为它是按正常价格的百分比计算的)。所以我精心设计了适当的查询来实现我想要的,并注意到 ROUND() 函数的一个非常奇怪的行为。

在某些情况下,当第三个十进制数字为 5(即 .165)时,它会被截断为 0.16,而在其他情况下,它会四舍五入为 0.17,当然,对于任何其他小数点后第三位为 5 的数字也会发生这种情况!这怎么可能?这是查询:

SELECT CODE, FWHSPRICE, RTLPRICE, CASE WHEN ISNULL(FWHSPRICE, 0) = 0 THEN RTLPRICE ELSE FWHSPRICE END AS REGULAR, ROUND(FLDFLOAT3, 2) AS SALE
FROM MATERIAL
WHERE COMID = 12
AND FLTID1 = 1

这是两个记录集之间比较的屏幕截图,左侧没有 ROUND() 查询,右侧有 ROUND()

在此处输入图片说明

PS:如果您希望我导出数据进行复制,能否请您向我解释如何为您创建合适的 INSERT 语句?整个表有很多字段和行,我不知道如何设置 SSMS 来做到这一点。我来自 MySQL,所以 SQL Server 的这个“领域”对我来说太陌生了......在此先感谢您。

亚伦·伯特兰

是的,你混合了两种有自己古怪行为的东西(恕我直言)。老实说,float除非我需要 float 的特定属性,否则我不会使用它,但是如果您坚持使用这种数据类型......

我会首先使用额外的小数位(甚至可能是 2)floatto转换decimal,然后使用另一个转换为舍入而不是舍入本身。例如:

DECLARE @x TABLE(x float);

INSERT @x(x) VALUES(0.615),(0.165),(0.415),(0.414);

SELECT 
  x, 
  bad    = ROUND(x, 2), 
  better = CONVERT(decimal(10,2), CONVERT(decimal(10,3), x))
FROM @x;

结果:

X 坏的 更好的
0.615 0.61 0.62
0.165 0.17 0.17
0.415 0.41 0.42
0.414 0.41 0.41

如果您有类似的值0.4149,您可以看到额外的小数位将如何防止四舍五入(除非这是您想要的行为):

DECLARE @f float = 0.4149;

SELECT source     = @f,
       round_up   = CONVERT(decimal(10,2), CONVERT(decimal(10,3), @f)),
       round_down = CONVERT(decimal(10,2), CONVERT(decimal(10,4), @f));

结果:

来源 围捕 舍入
0.4149 0.42 0.41

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章