0

如何创建一个返回浮点数(ChargeTotal)的函数?

ChargeTotal 基于使用批次数的渐进表。

num of batches     | charge
----------------------------
1-10               |  0
11-20              |  50
21-30              |  60
31-40              |  70
40+                |  80

如果批次数为 25 则

num of batches     | charge
----------------------------
1-10               |  0
11-20              |  50*10
21-30              |  60*5
----------------------------
total              |  800 <number I need to be returned(ChargeTotal)

到目前为止,我已经提出了以下内容,但我不确定如何获得每个循环的总数,或者是否可以执行多个 FOR 语句:

CREATE OR REPLACE FUNCTION ChargeTotal
RETURN FLOAT IS

total FLOAT;

BEGIN 

    FOR a in 1 .. 10 LOOP 

    FOR a in 11 .. 20 LOOP 

    FOR a in 21 .. 30 LOOP 

    FOR a in 40 .. 1000 LOOP 

    RETURN Total;

END ChargeTotal;
4

2 回答 2

0

我认为您可以通过单个 sql 进行计算而无需复杂的功能

逻辑是:

你有每个“乐队”的权重

计算每一行的“带”

count(*) over计算每个“带”中的行数

加入您的体重表以获得每个乐队的 sub.total

用于rollup获得总计

sql

  select r.num_of_batches
          ,sum(r.subtotal_charge)
     from (
    with weights as
    (select 1 as num_of_batches, 0 as charge from dual
    union all
    select 2 as num_of_batches, 50 as charge from dual
    union all
    select 3 as num_of_batches, 60 as charge from dual
    union all
    select 4 as num_of_batches, 70 as charge from dual
    union all
    select 5 as num_of_batches, 80 as charge from dual
    ) 
    select distinct n.num_of_batches
     , w.charge
     , count(*) over (partition by n.num_of_batches) as cnt
     , count(*) over (partition by n.num_of_batches) * charge as subtotal_charge
    from (
    select num, case when floor(num / 10) > 4 then 5 else floor(num / 10)+1 end as num_of_batches
       from tst_brances b
    ) n
    inner join weights w on n.num_of_batches = w.num_of_batches
    order by num_of_batches
    ) r
    group by ROLLUP(r.num_of_batches)

填充测试数据

    create table tst_branches(num int);

    declare 
     i int;
    begin 
      delete from tst_brances;
      for i in 1..10 loop
        insert into tst_brances(num) values (i);
      end loop;

      for i in 11..20 loop
        insert into tst_brances(num) values (i);
      end loop;

      for i in 21..25 loop
        insert into tst_brances(num) values (i);
      end loop;

      for i in 31..32 loop
        insert into tst_brances(num) values (i);
      end loop;


      for i in 41..43 loop
        insert into tst_brances(num) values (i);
      end loop;


      for i in 51..55 loop
        insert into tst_brances(num) values (i);
      end loop;

     commit;  
    end;

结果

1   1   0
2   2   500
3   3   360
4   4   140
5   5   640
6       1640
于 2017-05-22T20:13:19.730 回答
0

好的,考虑到现在我没有可用的数据库来测试这个(可能有一些语法错误等)。

但我在想一些沿着这行代码的东西......

 function ChargeTotal(xin number) return number is
     cursor mycursor is 
     select lowLimit,highLimit,charge 
     from progressive_table order by lowLimit;
     sum number;
     segment number; 
     x number;
    begin
     sum:=0;
     x  :=xin;
     for i in mycursor loop
       segment := (i.highLimit-i.lowLimit)+1;
       x := greatest ( x - segment,x);
       sum := sum + segment*i.charge;
       if (x<segment) then
         return sum; 
       end if;
      end loop;
    return sum;
   end;
于 2017-05-22T19:50:18.303 回答