SQL Server ROUND() 不适用于以 1 结尾的 FLOAT

标签 sql rounding

我改变了我的例子来使用 FLOAT ......太多人被整个 NVARCHAR 事情所困扰。我们没有将数字存储在数据库中作为 NVARCHAR。我只是以 NVARCHAR 为例。我用 FLOAT 得到了相同的结果。

对于某些 FLOAT,我们遇到了 SQL Server ROUND() 问题

声明@EXCHANGE_RATE FLOAT
设置@EXCHANGE_RATE = 1.327810000000000000000
选择回合(@EXCHANGE_RATE,6,1)
设置@EXCHANGE_RATE = 1.327820000000000000000
选择回合(@EXCHANGE_RATE,6,1)

第一个返回:1.327809
第二个返回:1.32782

您会认为第一个会返回 1.32781,而不是 1.327809。

这是 ROUND 中的功能还是错误?有什么简单的方法吗?

谢谢!

基于 Mat 将它们转换为 DECIMAL 的想法,这是有效的......它很难看,但有效。我使用 10 的原因是我查看了我们的数据库,这似乎是我们存储的最长的数字。另外我需要将它转换回 FLOAT 因为他们不想看到任何尾随的 0

声明@EXCHANGE_RATE FLOAT
设置@EXCHANGE_RATE = 1.327810000000000000000
SELECT CAST(ROUND(CAST(@EXCHANGE_RATE AS DECIMAL(28,10)),6,1) 作为 float )

最佳答案

试试这个查询。

SELECT
  ROUND('1.3278100',6,0)                     AS x0,
  ROUND('1.3278200',6,0)                     AS y0,
  ROUND('1.3278100',6,1)                     AS x1,
  ROUND('1.3278200',6,1)                     AS y1,

  ROUND(CAST( '1.3278100' AS FLOAT), 6, 0)   AS a0,
  ROUND(CAST( '1.3278200' AS FLOAT), 6, 0)   AS b0,
  ROUND(CAST( '1.3278100' AS FLOAT), 6, 1)   AS a1,
  ROUND(CAST( '1.3278200' AS FLOAT), 6, 1)   AS b1,

  ROUND(CAST( '1.3278100' AS DECIMAL(9,8)), 6, 0)   AS i0,
  ROUND(CAST( '1.3278200' AS DECIMAL(9,8)), 6, 0)   AS j0,
  ROUND(CAST( '1.3278100' AS DECIMAL(9,8)), 6, 1)   AS i1,
  ROUND(CAST( '1.3278200' AS DECIMAL(9,8)), 6, 1)   AS j1
;

http://sqlfiddle.com/#!6/d41d8/15607

这向我表明的是 ROUND()正在隐式转换您的 VARCHAR值为 FLOAT在截断它们之前。

由于 FLOAT 无法准确表示 1.327810,您实际上是在截断 1.3278099999999(或类似的值)。

因此,简而言之,在截断之前将它们显式转换为 DECIMAL。或者干脆不要将数字数据存储为字符串...

关于SQL Server ROUND() 不适用于以 1 结尾的 FLOAT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22230957/

相关文章:

java - 有没有办法去掉5舍入和向上舍入的奇偶规则?

java - 使用 GUI 输出框四舍五入到不同的小数位

php - 回显数据作为输入值

sql - View 上的查询运行速度比直接查询慢 - 在 Oracle 中

php - MySQL - 在不存在的地方插入

sql - Visual Studio 2019 数据源窗口不允许我添加数据库文件

sql - 使用 select 语句在创建表语法中定义默认列值

c++ - boost::format 给出的结果与 round 不同

iphone - 如何将应用程序图标的角变成圆角

python - 如何防止Python中的舍入