结果是什么

时间:2019-06-14 08:50:57

标签: sql sql-server

以下查询给出的输出为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的结果?

2 个答案:

答案 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,仅格式化字符串。确实这里有矛盾之处。

STRrounding 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