计算通话时长的数学公式

时间:2009-01-30 21:48:59

标签: sql math formula query-help

几年前我在一家电信公司工作,我必须根据以下算法生成一个计算呼叫持续时间的公式:

  • t1是第一个时期
  • t2是经常性的时期
  • RCT是实际通话时间(以秒为单位)
  • CD是有效的通话时长(用于计费)

如果RCT小于t1,则CD等于t1
如果RCT大于t1,则CD = t1 + x * t2,其中x将“RCT”“舍入”到t2的下一个最大倍数。

此算法转换为:“第一个t1秒充电,然后每隔t2秒充电一次”。

示例:

t1  t2  RCT CD  
60  10  48  60
60  10  65  70
60  10  121 130
30  20  25  30
30  20  35  50
30  20  65  70

你能创建一个能够返回“呼叫持续时间”CD的函数/ SQL吗?

不使用if then else ......?

3 个答案:

答案 0 :(得分:4)

假设int列:

SELECT t1
    ,t2
    ,RCT
    CASE
    WHEN RCT < t1
        THEN t1 
    ELSE
        t1 + t2 * ((RCT - t1) / t2 + SIGN((RCT - t1) % t2))
    END AS CD

但我想还有一个案例,让我看看能否摆脱它。

仅使用整数运算(仍然不是ANSI):

SELECT  t1
       ,t2
       ,RCT
       ,CD
       ,t1 + SIGN(RCT / t1) * t2 * ((RCT - t1) / t2 + SIGN((RCT - t1) % t2)) AS CalcCD
FROM    Calls

答案 1 :(得分:2)

编辑:进一步简化,并修复&lt; vs&lt; =错误。

没有浮点并且可以访问我有权访问的每个数据库:

create table calls (t1 int, t2 int, rct int, cd int)

insert into calls (t1, t2, rct, cd) 
values (60, 10, 48, 60)

insert into calls (t1, t2, rct, cd) 
values (60, 10, 65, 70)

insert into calls  (t1, t2, rct, cd)
values (60, 10, 121, 130)

insert into calls  (t1, t2, rct, cd)
values (30, 20, 25, 30)

insert into calls  (t1, t2, rct, cd)
values (30, 20, 35, 50)

insert into calls  (t1, t2, rct, cd)
values (30, 20, 65, 70)

--Additional test to show that it works
insert into calls  (t1, t2, rct, cd)
values (60, 10, 70, 70)

select t1, t2, rct, cd, 
t1 + case when rct <= t1 
  then 0 
  else ( (rct-1-t1) / t2 + 1) * t2 end as CalceCD
from calls

结果:

t1          t2          rct         cd          CalceCD
----------- ----------- ----------- ----------- -----------
60          10          48          60          60
60          10          65          70          70
60          10          121         130         130
30          20          25          30          30
30          20          35          50          50
30          20          65          70          70
60          10          70          70          70

(6 row(s) affected)

您可以自由地将该函数创建为UDF或您的SQL环境允许清理选择的任何内容。

编辑:是,楼层和偏移量为1可以避免浮动数学。

答案 2 :(得分:2)

我会用:

t1 + t2*ceiling( (rct - t1 + abs(rct - t1))*1.00/(2*t2) )

或者:

t1 + t2*ceiling( Cast((rct - t1 + abs(rct - t1)) as float)/(2*t2) )