在plqsl中基于每个月的总计算总计的函数/程序

时间:2018-01-29 14:38:58

标签: oracle stored-procedures plsql

我需要有关如何编写存储过程或函数的建议,以便根据每个月的总和计算总数。让我们说:

  • 1月份的目标收入= 20K,然后是1个月:20K * 31(1月份的总天数)
  • 2月份的目标收入= 19K,然后是1个月19K * 28(2月份的总天数)

我需要总计到给定的日期。例如:

date_param = 2018年2月25日。然后总计=(20K * 31)+(19K * 25)

如何在pl / sql中写这个?

谢谢。

2 个答案:

答案 0 :(得分:0)

你的问题仍然很明确,所以这是我的假设。

  1. 每日目标存储在一个结构为的表中 (month_no number, daily_tgt number)
  2. 每年的目标都是相同的。
  3. 计算从当年的第一个月开始。
  4. 没有必要处理闰年。
  5. 提出的问题排除了处理非工作日的必要性。
  6. 此解决方案是返回计算总数的函数。

    create or replace function get_target_sum 
         (p_cutoff in date)
         return number
    as
        rv number;
    begin
        select sum(daily_tgt * no_of_days) 
        into rv
        from (
        select daily_tgt
               , case when month_no < to_number(to_char(p_cutoff, 'MM'))
                   then to_number(to_char(last_day(to_date(month_no,'MM')), 'DD'))
                   else to_number(to_char(p_cutoff, 'DD')) 
                 end  as no_of_days
            from targets
            where month_no <= to_number(to_char(p_cutoff, 'MM'))
          );
        return rv;
    end;
    /
    

    备注

    • 按月数存储每日目标可以更轻松地过滤WHERE子句中截止日期之前的月份。
    • 将月份编号投射到某个日期允许我们推导出月份的最后一天,从中获取整数月份的天数。
    • 最后一个月,我们只需要截止日期的那一天。

答案 1 :(得分:0)

在说明如何获得每月费率时,您的问题并不十分明确。我假设了一些事情并提供了我的解决方案如下:

1)创建了一个表mnthly_tgt,可存储每月费率。

2)该功能将采用输入日期,然后返回一年中过去几个月的总和。

表定义:

Create table mnthly_tgt(mnth number, tgt_amt number);

insert into mnthly_tgt values(1 , 15);
insert into mnthly_tgt values(2, 20);
insert into mnthly_tgt values(3 , 12);
insert into mnthly_tgt values(4 , 10);
insert into mnthly_tgt values(5 , 11);
insert into mnthly_tgt values(6, 15);
insert into mnthly_tgt values(7, 20);

功能:

Create or replace function Ret_Tot(ipt_dt date)
return number 
is

v_curr_mnth  number;
v_curr_days  number;
v_tot_amt    number;
v_sql varchar2(400);
v_date   date;
v_num_of_days  number;
cntr number:=0;

begin

 -- Calculating total for current month.

   Select  to_char(ipt_dt,'MM')  col1      -- Current Month   
          ,to_char(ipt_dt,'dd')   col3      -- Days in Current Month  
    INTO 
       v_curr_mnth ,
       v_curr_days             
   from DUAL;

   -- Current Month Total
   v_tot_amt: = v_curr_days *  (Select tgt_amt from mnthly_tgt where mnth = v_curr_mnth);


  --Calculation for previous months

   For i in (Select  to_char(ipt_dt,'MM') - LEVEL  col1  
             from Dual
             CONNECT BY LEVEL < to_char(col,'MM')   
   Loop

     cntr := cntr + 1;

     v_sql:='Select ipt_dt - INTERVAL '|| cntr ||' MONTH from DUAL'  ;   

     Execute Immediate v_sql INTO V_DATE;

     --calculating no. of days of previous months  
     v_sql:='SELECT EXTRACT(DAY FROM LAST_DAY('|| V_DATE ||'))  FROM dual';

     Execute Immediate v_sql INTO  v_num_of_days ;

     --Summing up total      
     v_tot_amt: = v_tot_amt + ( v_num_of_days * (Select tgt_amt from mnthly_tgt where mnth = i.col1));

   END LOOP; 

 return v_tot_amt;

end;

PS:经过测试。