SQL Server:十进制精度/小数位数产生奇怪的结果

2024-06-25

我正在为一个项目编写一些 SQL,我注意到 SQL Server 中一些看似奇怪的行为,涉及除以小数时的答案。

以下是一些示例,说明了我所看到的行为:

DECLARE @Ratio Decimal(38,16)
SET @Ratio = CAST(210 as Decimal(38,16))/CAST(222 as Decimal(38,16));

select @Ratio -- Results in 0.9459450000000000

DECLARE @Ratio Decimal(38,16)
SET @Ratio = CAST(210 as Decimal)/CAST(222 as Decimal);

select @Ratio -- Results in 0.9459459459459459

对于上面的代码,(看似)不太精确的查询答案给出了更精确的值作为答案。当我将股息和除数都投射为Decimal(38,16),我得到一个小数位数为 6 的数字(将其转换为Decimal(38,16)再次导致 0 填充刻度)。

当我将被除数和除数转换为默认的十进制(没有手动设置精度或小数位数)时,我得到了结果小数位数的完整 16 位数字。

出于好奇,我开始使用以下查询进行更多实验:

select CAST(210 as Decimal(38,16))/CAST(222 as Decimal(38,16)) --0.945945
select CAST(210 as Decimal(28,16))/CAST(222 as Decimal(28,16)) --0.9459459459
select CAST(210 as Decimal(29,16))/CAST(222 as Decimal(29,16)) --0.945945945

正如您所看到的,当我提高精度时,答案的范围似乎会减小。我看不出结果的规模与被除数和除数的规模或精度之间的相关性。

我发现其他一些 SO 问题指向 msdn 文档中的一个位置,其中指出小数运算期间产生的精度和小数位数是通过对除数和被除数的精度和小数位数执行一组计算来确定的,并且:

结果精度和小数位数的绝对最大值为38。当结果精度大于38时,相应的小数位数会减小,以防止结果的整数部分被截断。

所以我尝试自己运行这些方程来确定除以 a 的输出是什么Decimal(38,16)进入另一个Decimal(38,16)看起来像,根据我的发现,我仍然应该得到比我得到的更精确的数字。

所以我要么做错了数学,要么这里发生了其他我错过的事情。我非常感谢你们中任何人提供的任何见解。

提前致谢...


The 文档 http://msdn.microsoft.com/en-gb/library/ms190476.aspx关于价值的魔力有点不完整6以及何时应用max函数,但这是我基于该文档的发现的表格。

正如它所说,除法的公式是:

结果精度=p1 -​​ s1 + s2 + 最大值(6, s1 + p2 + 1), 结果尺度 =最大值(6, s1 + p2 + 1)

而且,正如您自己所强调的那样,我们还有脚注:

结果精度和小数位数的绝对最大值为38。当结果精度大于38时,相应的小数位数会减小,以防止结果的整数部分被截断。

所以,这是我在电子表格中生成的内容:

p1 s1 p2 s2 prInit srInit prOver prAdjusted srAdjusted
38 16 38 16 93     55     55     38         6
28 16 28 16 73     45     35     38         10
29 16 29 16 75     46     37     38         9

所以,我正在使用pr and sr来表示结果的精度和范围。这prInit and srInit公式与文档中的公式完全相同。正如我们所看到的,在所有 3 种情况下,结果的精度都远远大于38因此脚注适用。prOver只是max(0,prInit - 38)- 如果脚注适用,我们必须将精度调整多少。prAdjusted只是prInit - prOver。我们可以看到,在这三种情况下,结果的最终精度都是38.

如果我应用same调整因子到尺度然后我会得到结果0, 10 and 9。但我们可以看到您的结果(38,16)案例规模为6。所以我相信这就是max(6,...文档的一部分实际上适用。所以我的最终公式srAdjusted is max(6,srInit-prOver)现在是我的最后一场Adjusted值似乎与您的结果相匹配。


当然,如果我们查阅文档decimal http://msdn.microsoft.com/en-us/library/ms187746.aspx,我们可以看到default精度和小数位数,如果您不指定它们,则为(18,0),所以这是当您未指定精度和小数位数时的行:

p1 s1 p2 s2 prInit srInit prOver prAdjusted srAdjusted
18 0  18 0  37     19     0      37         19
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL Server:十进制精度/小数位数产生奇怪的结果 的相关文章

  • SQL SERVER - COALESCE() 函数的问题

    我有一个由存储过程包装的 SQL 函数 ALTER FUNCTION dbo GetObjList filterUID int NULL filterSID varchar 32 NULL RETURNS TABLE AS RETURN S
  • 有没有办法刷新 Oracle 中 PL/SQL 的输出?

    我有一个从 shell 脚本中调用的 SQL 脚本 需要很长时间才能运行 目前它包含dbms output put line不同点的声明 这些打印语句的输出会出现在日志文件中 但仅在脚本完成后才会出现 有什么方法可以确保脚本运行时输出出现在
  • Python 和 SQLite:插入表

    具有以下表架构 tablename name varchar 100 age int sex char 1 有一个list有 3 行 每行代表一个表行 row1 laks 444 M row2 kam 445 M row3 kam 445
  • 加载SSIS包时出错

    我正在尝试在 SQL Server 2008R2 上执行 SSIS 包 该脚本检索远程服务器上的数据并将其复制到本地数据库 该作业每小时安排一次 SQL 代理使用代理向远程计算机验证自身身份 身份验证似乎没问题 但在加载 SSIS 包期间出
  • 一次性将所有 SQL Server 表导出为 txt 或 csv

    我有数百个 SQL Server 表需要导出到 txt 或 csv 文本限定符和 划定的 导入 导出向导一次仅允许一张表 有没有更好的方法 工具 脚本来同时完成这一切 Thanks 您可以使用以下命令对 BCP 执行某些操作 SELECT
  • 检查行是否存在,Laravel

    我有以下数据库结构 items id name user id users table id name user favorites table id user id item id 在我的项目永久链接页面上 我有一个 添加到收藏夹 按钮
  • 主键和代理键有什么区别?

    我用谷歌搜索了很多 但没有找到带有示例的确切直接答案 任何例子都会更有帮助 主键是表中的唯一键 您选择它可以最好地唯一标识表中的记录 所有表都应该有一个主键 因为如果您需要更新或删除一条记录 您需要知道如何唯一标识它 代理键是人工生成的键
  • 从表变量中获取列的明确名称

    我可以这样声明一个表变量 DECLARE tv source TABLE c1 int providerName varchar 50 providerSMS varchar 50 如果我执行以下命令 我会看到类似于以下内容的表名称 468
  • 如何在 SQL 中将 varchar 列拆分为多个值?

    我有这个 SQL Select 语句 SELECT AD Ref List Value FROM AD Ref List WHERE AD Ref List AD Reference ID 1000448 这是 SELECT 的结果 为了限
  • ISDATE 相当于 DB2

    我有一个包含字符格式日期的表 我想检查日期的格式 请让我知道如何在 DB2 中做到这一点 我知道有一个函数 ISDATE 但它在 DB2 中不起作用 我在 AS400 上使用 db2 作为日期基础 请帮助我 实际上 看起来 DB2 for
  • 从 JDBC MSSQL 获取返回值

    我使用 Microsoft SQL Server JDBC Driver 2 0 通过 Java 连接到 SQL Server 2005 如何从存储过程中获取返回值 我正在做类似的事情 Connection connection dataS
  • INSERT INTO 存储过程的输出

    我正在编写一个存储过程 首先在表中插入一个新行 然后 另一个查询需要此查询生成的 ID 是否可以使用 OUTPUT 访问预先生成的 ID 这就是我到目前为止所做的 这几乎是一个猜测 但没有成功 ALTER PROCEDURE dbo add
  • 为什么使用 SQL Server Express 添加的记录未显示在 SQL Server Management Studio 中?

    我正在测试大量的数字音乐文件记录 我的添加例程是 foreach AlbumModel albumModel in albs try Album album GetAlbum albumModel cmd CommandText inser
  • 限制 SQL 查询的响应时间

    我在这里发布了一个关于我的 gridview 绑定的问题 将GridView与多条记录绑定 https stackoverflow com questions 5599704 bind gridview with many records
  • 如何在SQL Server数据库的所有表的所有列中搜索特定字符串?

    我们想要在拥有大约 120 个表的所有数据库中搜索一个字符串 即 Hello World 我们考虑过像 mysql dump 一样进行转储 但它以奇怪的 bak 格式出现 应在每个表的每一列中进行搜索 任何类型的脚本都可以做到这一点 或者这
  • 即使为空也显示值

    我正在使用以下内容显示过去 7 天内添加的产品计数 即使 COUNT 0 我是否可以以某种方式定制查询以显示过去 7 天的所有产品 查询现状 SELECT DAYNAME dateadded DAY COUNT COUNT FROM pro
  • 通过sql视图向多个表插入数据

    mysql 有没有办法通过视图向多个表插入数据 MySQL 参考手册对于可更新视图是这样说的 一些视图是可更新的 也就是说 您可以在诸如以下的语句中使用它们UPDATE DELETE or INSERT更新基础表的内容 为了使视图可更新 必
  • 如何使用 SQL 计算一条路线的行驶次数?

    我需要确定在给定的日期范围内每辆车行驶特定路线的次数 但建立在数据库之上的 GPS 管理软件没有此功能 该数据库包含多个存储 GPS 路线和位置数据的表 路线由多个位置和序列号组成 位置是附加到名称的一组上限和下限纬度 经度值 车辆每分钟将
  • 邮政编码 10 位数字字符使用的约束检查

    我有一张桌子 上面有Char 10 列类型 命名postal Code我需要对所有值进行约束检查 就像 10 位数字一样1234567890没有别的 我使用以下内容 CONSTRAINT CH PCDigit CHECK PostalCod
  • 由于表扫描,表值参数的性能较低

    我有一个将参数传递给 SQL 过程的应用程序 其中一个参数是表值参数 其中包含要包含在 where 子句中的项目 因为当我将 TVP 连接到具有 200 万行的表时 表值参数没有附加任何统计信息 所以查询速度非常慢 我还有什么选择 同样 目

随机推荐