PL / SQL函数,用于计算给定日期范围的月平均值

时间:2015-01-14 07:08:15

标签: sql oracle plsql oracle11g

假设

1st jan count is 20   
2nd jan count is 12   
3rd jan count is 0   
.................   
..................  
31st jan count is 17 

我需要一个可以找到月平均值的函数。在这种情况下它应该是20+12+17/3因为我不想使用计数为0的那天

我试过了: -

create function(p_date IN Date)
return number is

cursor c_num is
 select  count(distinct attribute8) from mtl_material_transactions  where trunc(transaction_date)=p_date;

l_num number:=0

begin
open c_num;
fetch c_num into l_num;
close c_num;

return sum(l_num);

end;

但它不按照我的要求工作。请帮助我。我需要找到给定日期范围的月平均值 01-April-2013-Mar-2014。

测试数据为: -

create table kk1 ( ATTRIBUTE8 varchar2(30), TRANSACTION_DATE date );  

insert into kk1 values ( 'LP001', to_date('08.01.2015 15:21:59', 'dd.mm.yyyy hh24:mi:ss'));   
insert into kk1 values ( 'LP002', to_date('08.01.2015 15:24:33', 'dd.mm.yyyy hh24:mi:ss'));   
insert into kk1 values ( 'LP004', to_date('08.01.2015 15:41:51', 'dd.mm.yyyy hh24:mi:ss'));   
insert into kk1 values ( 'LP005', to_date('08.01.2015 15:43:38', 'dd.mm.yyyy hh24:mi:ss'));   
insert into kk1 values ( 'LP001', to_date('14.01.2015 11:36:13', 'dd.mm.yyyy hh24:mi:ss'));   
insert into kk1 values ( 'LP002', to_date('14.01.2015 11:38:24', 'dd.mm.yyyy hh24:mi:ss'));   
insert into kk1 values ( 'LP001', to_date('14.01.2015 11:40:09', 'dd.mm.yyyy hh24:mi:ss')); 

2 个答案:

答案 0 :(得分:1)

我不确定我理解你的要求。如果您想计算每个月的平均值,我希望您的函数可以采用日期范围(而不仅仅是单个日期)并返回多个数字,即日期范围内每个月的数字。 / p>

以下查询是否计算出您要查找的内容?

SELECT AVG(attribute8) average, TRUNC(transaction_date, 'MONTH') mon
FROM mtl_material_transactions
WHERE transaction_date BETWEEN TO_DATE('01-Apr-2013', 'DD-MON-YYYY') AND TO_DATE('31-Mar-2014', 'DD-MON-YYYY')
  AND attribute8 <> 0
GROUP BY TRUNC(transaction_date, 'MONTH');

答案 1 :(得分:0)

我的问题的答案是: -

FUNCTION Get_attr_avg (p_from_date IN DATE,
                       p_to_date   IN DATE)
RETURN NUMBER
IS
  CURSOR c_attr_avg IS
    SELECT Avg(attr_per_day)
    FROM   (SELECT Count(DISTINCT attribute8) attr_per_day,
                   Trunc(transaction_date)    day
            FROM   mtl_material_transactions
            WHERE  transaction_date BETWEEN p_from_date AND p_to_date
                   AND attribute8 IS NOT NULL
            GROUP  BY Trunc(transaction_date))
    GROUP  BY To_char(day, 'MON-YYYY');
  l_attr_avg NUMBER := 0;
BEGIN
    OPEN c_attr_avg;
    FETCH c_attr_avg INTO l_attr_avg;
    CLOSE c_attr_avg;

    RETURN l_attr_avg;
EXCEPTION
  WHEN OTHERS THEN
             RETURN 0;
END get_attr_avg;