SQL 中数值型数据截取及四舍五入
例一:
-- 将两个数值分别截取只保留两位小数 ( 注意此时字段默认为 decimal )
select CAST ( 10.097 as decimal ( 10, 2)) as [10.097 截取前 ]
, CAST ( 10.094 as decimal ( 10, 2)) as [10.094 截取前 ]
, CAST ( 10.145 as decimal ( 10, 2)) as [10.145 截取前 ]
例二:
-- 再次将两个数值分别截取只保留两位小数 ( 注意此时字段类型为 float )
declare @a float , @b float , @c float
set @a = 10.097
set @b = 10.094
set @c = 10.145
select CAST ( @a as decimal ( 10, 2)) as [10.097 截取前 ]
, CAST ( @b as decimal ( 10, 2)) as [10.094 截取前 ]
, CAST ( @c as decimal ( 10, 2)) as [10.145 截取前 ]
在做精度和小数位数的转换时 ,也要考虑 decimal 和 float 的不同类型字段的区别 。
否则用 Round 函数也是一样的效果 。
比如 :
declare @a float , @b float , @c float
set @a = 10.097
set @b = 10.094
set @c = 10.145
select ROUND ( @a , 2) as [10.097 进位前 ]
, ROUND ( @b , 2) as [10.094 进位前 ]
, ROUND ( @c , 2) as [10.145 进位前 ]
--result:
10.097 进位前 10.094 进位前 10.145 进位前
---------------------- ---------------------- ----------------------
10.1 10.09 10.14
( 1 行受影响 )
总结 :当字段类型为 float 时 ,进行四舍五入有时会有奇怪的结果产生 ,比如
declare @a float , @b float , @c float
set @a = 0.134
set @b = 0.145
set @c = 0.146
select ROUND ( @a , 2) as [0.134 进位前 ]
, ROUND ( @b , 2) as [0.145 进位前 ]
, ROUND ( @c , 2) as [0.146 进位前 ]
--result:
0.134 进位前 0.145 进位前 0.146 进位前
---------------------- ---------------------- ----------------------
0.13 0.14 0.15
( 1 行受影响 )
当字段类型为 decimal 时 ,对于高精度的小数位四舍五入时 ,并没有产生那样奇怪的结果 。比如 :
declare @a decimal ( 5, 3) , @b decimal ( 5, 3) , @c decimal ( 5, 3)
set @a = 0.134
set @b = 0.145
set @c = 0.146
select ROUND ( @a , 2) as [0.134 进位前 ]
, ROUND ( @b , 2) as [0.145 进位前 ]
, ROUND ( @c , 2) as [0.146 进位前 ]
--result:
0.134 进位前 0.145 进位前 0.146 进位前
---------------------- ---------------------- ----------------------
0.130 0.150 0.150
( 1 行受影响 )
所以我们在进行小数位的计算或转换时 ,我会优先考虑 decimal 类型的数值 。比如 在例一中默认的字段类型即是 decimal ,下面我们来看一下:
--1 、将 0.145 导入临时表
select 0.145 a
into #a
( 1 行受影响 )
-- 查看临时表中 a 字段类型
select
[ 表名 ] = c . Name ,
[ 列名 ] = a . Name ,
[ 标识 ] = case when is_identity = 1 then '√' else '' end ,
[ 类型 ] = b . Name
from
sys . columns a
left join
sys . types b on a . user_type_id = b . user_type_id
inner join
sys . objects c on a . object_id = c . object_id
where left( c . Name , 2)= '#a' and a . name = 'a'
-- 结果如下图示:
所以回看例一 ,在进行数据转换时 ,默认的字段类型仍是 decimal 。
附图 数据类型转换时的行为规范