【问题标题】:Progressive LOOP Statement ORACLE渐进式循环语句 ORACLE
【发布时间】:2017-05-22 18:46:22
【问题描述】:

如何创建一个返回float(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;

【问题讨论】:

  • 你有没有尝试过?
  • 我假设我可以使用 FOR...LOOP 但我不确定语法,因为我需要一个计数器或其他东西来跟踪何时进入下一段.我只是从一个循环开始并添加,但希望有人能让我朝着正确的方向前进。

标签: oracle function loops plsql progressive


【解决方案1】:

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

但我正在考虑这行代码......

 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;

【讨论】:

  • 我会试试这个。 ty
【解决方案2】:

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

逻辑是:

每个“乐队”都有权重

计算每一行的“带”

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

加入您的体重表以获得每个波段的小计

使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-11
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    • 2017-06-20
    • 2019-08-08
    相关资源
    最近更新 更多