SQL Server百分比计算

时间:2012-03-30 02:06:38

标签: sql-server function

我试图想出一种统一的方法来计算单个表中两列之间的百分比差异。 有时num1为零,在这种情况下,计算的差异应为100%。 有时num2为零,在这种情况下,计算的差异应为100%。 有时num1和num2之间的差异非常大,在这种情况下,计算的差异将是100%。

以下是表格中的示例摘录:

declare @numtable table ( num1 decimal(10,3) , num2 decimal(10,3) )
insert into @numtable values ( 160 , 161.5 )
insert into @numtable values ( 439 , 377 )
insert into @numtable values ( 100 , 1 )
insert into @numtable values ( 1 , 100 )
insert into @numtable values ( 0 , 20 ) 
insert into @numtable values ( 20 , 0 ) 

我做了一个看起来如下的破坏的select语句。

select num1 , num2 , Abs(100- ( 100 * cast( cast(num1 as decimal(6,3)) / cast(num2 as decimal(10,3) ) as decimal(6,3) ) ) ) as percentdiff
from @numtable

这使得:

num1         num2         percentdiff
------------ ------------ -------------
160.000      161.500      0.900
439.000      377.000      16.400
100.000      1.000        9900.000
1.000        100.000      99.000
0.000        20.000       100.000

前3行都可以。 第五行是OK。 第六行从不显示,因为它会产生除零错误。

我希望我的结果集看起来像这样:

num1         num2         percentdiff
------------ ------------ -------------
160.000      161.500      0.900
439.000      377.000      16.400
100.000      1.000        9900.000
1.000        100.000      9900.000
0.000        20.000       100.000
20.000       20.000       100.000

我应该如何将我的选择更改为能够以我需要的方式返回的内容?

感谢。

2 个答案:

答案 0 :(得分:3)

我会在你的选择列表的第三项中使用case语句来测试除以0的错误。在别的做你的数学。就这么简单。

Select num1, num2,
 Case num2
 WHEN 0 Then 100
 Else Abs(100- ( 100 * cast( cast(num1 as decimal(6,3)) / cast(num2 as decimal(10,3) ) as decimal(6,3) ) ) ) 
 END as percentdiff

From @numtable

答案 1 :(得分:1)

请参阅here

你需要在除以零的情况下做一些额外的事情:

case when num1 <= 0 or num2 <= 0 or num1 = num2 then 100

select num1,num2,
case when num1 <= 0 or num2 <= 0 or num1 = num2 then 100
  else
   case when 
   cast(
     cast(abs(num1-num2) as decimal(8,5))
     /
     cast(case when num1>num2 then num2 else num1 end as decimal(8,5))
     * 100
   as decimal(8,2))
   > 100 then
     9900 
   else
    cast(
     cast(abs(num1-num2) as decimal(8,5))
     /
     cast(case when num1>num2 then num2 else num1 end as decimal(8,5))
     * 100
   as decimal(8,2))
   end
  end as percentage
from t