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 =
set @b =
set @c =
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 =
set @b =
set @c =
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 =
set @b =
set @c =
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 =
set @b =
set @c =
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 。

 

附图 数据类型转换时的行为规范