以下查询给出的输出为123.5
SELECT STR(123.45, 6, 1);
GO
但是..以下查询给出的输出为123.3
SELECT STR(123.35, 6, 1);
GO
为什么没有给出123.4的结果?
SELECT STR(123.45, 6, 1);
GO
SELECT STR(123.35, 6, 1);
GO
以下查询给出的输出为123.3
SELECT STR(123.35, 6, 1);
GO
为什么没有给出123.4的结果?
答案 0 :(得分:3)
从documentation中获得SQL Server的STR
函数:
[第一个参数]是带有小数点的近似数字(浮点)数据类型的表达式。
从我的本地测试中,即使我传递了DECIMAL
值,您看到的不精确度仍在继续,并且输入参数仍被视为浮点数。
那就是:
SELECT STR(CAST(123.45 AS DECIMAL(10,2)), 6, 1)
仍然返回123.5
。
如果您想在SQL Server中精确截断数字值,则只需尝试转换为DECIMAL
类型,例如
SELECT CAST(123.45 AS DECIMAL(10,1))
返回您期望的123.4
。
答案 1 :(得分:0)
长话短说,请使用FORMAT而非STR,仅格式化字符串。确实这里有矛盾之处。
STR
是rounding half to odd,这是....奇怪的行为。更常见的方法是round half to even,也称为Banker的舍入。两种策略都会使汇总的舍入误差最小化。
这就是为什么
SELECT STR(123.45, 6, 1),STR(123.35, 6, 1);
返回
123.5 123.3
STR
并不是舍入函数,而是字符串格式化函数。它产生的字符串不是要添加的。而且,T-SQL的ROUND
函数将取整为零和
SELECT round(123.45,1), round(123.35,1);
产生
123.50 123.40
Oracle,PostgreSQL和MySQL的ROUND行为相同,四舍五入。我怀疑这是标准的一部分,但我尚未找到相关链接。
FORMAT的功能要强大得多。它使用与.NET相同的格式字符串,并且四舍五入为零。
SELECT FORMAT(123.45, 'n1'), FORMAT(123.35, 'n1');
生产
123.5 123.4