【问题标题】:SQL Server truncates decimal points of a newly created field in a viewSQL Server 截断视图中新创建字段的小数点
【发布时间】:2011-04-08 21:25:11
【问题描述】:

我在 SQL Server 中有一个视图,如下所示:

select 6.71/3.41 as NewNumber

结果是1.967741(注意小数点后6位)->decimal (38,6)

我在计算器中尝试了同样的事情,但结果是1.967741935483871xxxx

我想强制 SQL Server 返回更准确的结果,例如 decimal(38,16) 我已经尝试了一些明显的东西,比如强制转换,但是 SQL Server 并没有改善输出我只是在最后得到一些尾随零,比如1.9677410000

有没有办法强制 SQL Server 不截断结果或给出更准确的结果?

【问题讨论】:

标签: sql-server tsql precision


【解决方案1】:

如果你想要decimal(38,16) 之类的东西,那么你需要在截断发生后转换输入而不是输出!

SELECT CAST(6.71 AS DECIMAL(38,18))/3.41 AS NewNumber

返回

1.9677419354838709

检查数据类型

SELECT 
SQL_VARIANT_PROPERTY(CAST(6.71 AS DECIMAL(38,18))/3.41, 'BaseType'),
SQL_VARIANT_PROPERTY(CAST(6.71 AS DECIMAL(38,18))/3.41, 'Precision'),
SQL_VARIANT_PROPERTY(CAST(6.71 AS DECIMAL(38,18))/3.41, 'Scale')

返回

numeric 38  16

编辑

这只是添加一个附加链接作为对 cme​​ts 的跟进。 decimaldecimal 转换 are described in BOL 的规则。该链接包含以下短语

*结果精度和小数位数的绝对最大值为 38。当一个 结果精度大于38, 相应的比例缩小到 防止结果的组成部分 不会被截断。

但是没有具体说明这种截断是如何执行的。 This is documented here.

【讨论】:

  • 为什么 Cast(6.71 as decimal(38,16))/Cast(3.41 as decimal(38,16)) 返回 1.967741?
  • 结果是数据类型decimal(38,6)。十进制除法结果的精度规则在这个链接msdn.microsoft.com/en-us/library/ms190476.aspxresultprecision=p1 - s1 + s2 + max(6, s1 + p2 + 1)result scale=max(6, s1 + p2 + 1)但是“当一个result精度大于38时,相应的scale被减小以防止积分截断结果的一部分”
  • 谢谢马丁,其他人都在工作,你的回答很全面
【解决方案2】:

这是一种解决方法,但我认为值得一提。

select ((6.71*10000)/(3.41*10000)) as NewNumber

这个查询:

SELECT 6.71/3.41, ((6.71*1000000)/(3.41*1000000)) as NewNumber

返回:

1.967741    1.96774193548387

【讨论】:

    【解决方案3】:

    文字 6.71 被视为具有固定精度的numeric。由于您正在进行除法,因此您正在更改小数位数,当准确性至关重要时,您不想使用它。如果您想将您的数字视为准确,您需要将查询中的分母转换为具有更大精度的 decimal 数据类型。这应该适合你:

    select 6.71 / cast(3.41 as decimal(18, 8)) as NewNumber
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-06
      相关资源
      最近更新 更多