7

私は数年前に通信会社で働いていましたが、次のアルゴリズムに従って通話時間を計算する数式を生成する必要がありました。

  • 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 を使わずに…?

4

3 に答える 3

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

しかし、まだ CASE が 1 つあると思います。それを取り除くことができるかどうか見てみましょう。

整数演算のみ (まだ ANSI ではありません):

SELECT  t1
       ,t2
       ,RCT
       ,CD
       ,t1 + SIGN(RCT / t1) * t2 * ((RCT - t1) / t2 + SIGN((RCT - t1) % t2)) AS CalcCD
FROM    Calls
于 2009-01-30T22:18:22.940 に答える
2

編集: さらに簡素化し、< vs <= エラーを修正しました。

浮動小数点はなく、私がアクセスできるすべてのデータベースで動作しました:

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 行)

関数をUDFとして自由に作成するか、SQL環境で選択をクリーンアップできるものなら何でも作成できます。

編集:はい、フロアとオフセットが1の場合、浮動計算が回避されます。

于 2009-01-30T22:10:34.873 に答える
2

I would use:

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

Or:

t1 + t2*ceiling( Cast((rct - t1 + abs(rct - t1)) as float)/(2*t2) )
于 2009-01-30T22:38:31.633 に答える