m.e*_*son 3 t-sql sql-server sql-server-2005
刚刚遇到一个有趣的:
declare @test as int
set @test = 47
select @test * 4.333
Run Code Online (Sandbox Code Playgroud)
返回 203.651
declare @test as int
set @test = 47
declare @out as int
set @out = (select @test * 4.333)
select @out
Run Code Online (Sandbox Code Playgroud)
返回 203
declare @test as int
set @test = 47
declare @out as int
set @out = round((select @test * 4.333),0)
select @out
Run Code Online (Sandbox Code Playgroud)
返回 204
现在我知道它为什么这样做了。这是因为存在从十进制到 int 的隐式转换,因此需要截断小数位(因此为 203),而如果我在隐式转换之前舍入,则会得到 204。
我的问题是为什么当 SQL Server 进行隐式转换时它不是也四舍五入? 我知道如果我有一个很大的数字,并且需要存储在一个小地方,我要做的第一件事就是将它四舍五入以尽可能接近原始数字。
这对我来说似乎并不直观。
这让我读了起来,答案似乎明显不令人满意,我在第4.4.1节数字特征中找到的最早的 SQL 参考(此处为ANSI 92 )指出
每当将精确或近似数值分配给表示精确数值的数据项或参数时,在四舍五入或截断后保留前导有效数字的近似值在目标的数据类型中表示。该值被转换为具有目标的精度和比例。是截断还是舍入的选择是实现定义的。
这让微软决定他们选择为 T-SQL 实现这两个中的哪一个,我假设为了简单起见,他们选择了截断。从维基百科关于四舍五入的文章看来,这在当时并不是一个罕见的决定。
有趣的是,根据我发现的文档,只有转换为整数会导致截断,其他的会导致舍入。尽管出于某种奇怪的原因,从moneyto的转换integer似乎与趋势相反,因为它被允许四舍五入。
From To Behaviour
numeric numeric Round
numeric int Truncate
numeric money Round
money int Round
money numeric Round
float int Truncate
float numeric Round
float datetime Round
datetime int Round
Run Code Online (Sandbox Code Playgroud)
表从这里。
| 归档时间: |
|
| 查看次数: |
1752 次 |
| 最近记录: |