2017-06-05 24 views
0

日付範囲の値に基づいてクエリのカウントを与えるPL/SQLプロシージャを作成しています。私は、日付範囲を動的に取得したいと私はそのためのカーソルを書いている。異なる日付範囲のコレクションに値を設定する

私はコレクションを使用しており、毎月のカウントを取得していますが、私が直面している問題は、コレクションに先月のカウントだけが入力されていることです。私はすべての月の数を取得したい。誰も助けることができますか?

この

は私が書かれている手順です:

create or replace 
Procedure Sample As 
    Cursor C1 Is 
     With T As (
      select to_date('01-JAN-17') start_date, 
       Last_Day(Add_Months(Sysdate,-1)) end_date from dual 
     ) 
     Select To_Char(Add_Months(Trunc(Start_Date,'mm'),Level - 1),'DD-MON-YY') St_Date, 
      to_char(add_months(trunc(start_date,'mm'),level),'DD-MON-YY') ed_date 
     From T 
     Connect By Trunc(End_Date,'mm') >= Add_Months(Trunc(Start_Date,'mm'),Level - 1); 

    Type T_count_Group_Id Is Table Of number; 
    V_count_Group_Id T_count_Group_Id; 
Begin 
    For I In C1 
    Loop 
     Select Count(Distinct c1) bulk collect Into V_Count_Group_Id From T1 
     Where C2 Between I.St_Date And I.Ed_Date; 
    End Loop; 
    For J In V_Count_Group_Id.First..V_Count_Group_Id.Last 
    Loop 
     Dbms_Output.Put_Line(V_Count_Group_Id(J)); 
    end loop; 
END SAMPLE; 

答えて

2

コレクションの内容ループの周りのたびに交換されたあなたのbulk collectクエリ。それはコレクションに追加されません(もしあなたが期待したものなら)。ループの後、最後のbulk collect(カーソルの最新月)の結果しか表示されません。

また、文字列として日付を比較しているようです(c2が文字列として格納されていない限り、それはさらに悪いことです)。 betweenが含まれているため、保存された時間の部分が深夜である場合は、毎月の初日のデータを2つのカウントで含むリスクがあります。日付範囲の等価チェックを使用する方が安全です。

カーソルを使用して日付を取得し、そのカーソル内の個々のクエリを取得する必要はありません。現在のカーソルクエリをターゲットテーブルに結合することができます。外部結合を使用して、 。カーソルが現在の年の開始までに、現在の年のすべての月を探しているように見えるので、それは多分に簡素化することができます。

:あなたは、あなたのコレクションを移入するためにそれを使用することができます

with t as (
    select add_months(trunc(sysdate, 'YYYY'), level - 1) as st_date, 
    add_months(trunc(sysdate, 'YYYY'), level) as ed_date 
    from dual 
    connect by level < extract(month from sysdate) 
) 
select t.st_date, t.ed_date, count(distinct t1.c1) 
from t 
left join t1 on t1.c2 >= t.st_date and t1.c2 < t.ed_date 
group by t.st_date, t.ed_date 
order by t.st_date; 

declare 
    type t_count_group_id is table of number; 
    v_count_group_id t_count_group_id; 
begin 
    with t as (
    select add_months(trunc(sysdate, 'YYYY'), level - 1) as st_date, 
     add_months(trunc(sysdate, 'YYYY'), level) as ed_date 
    from dual 
    connect by level < extract(month from sysdate) 
) 
    select count(distinct t1.c1) 
    bulk collect into v_count_group_id 
    from t 
    left join t1 on t1.c2 >= t.st_date and t1.c2 < t.ed_date 
    group by t.st_date, t.ed_date 
    order by t.st_date; 

    for j in v_count_group_id.first..v_count_group_id.last 
    loop 
    dbms_output.put_line(v_count_group_id(j)); 
    end loop; 
end; 
/

実際に必要とするものではないかもしれないが、月が明記されていなくても、カウントを保存/表示するだけですが、カウントが順序付けされると、少なくとも、コレクションの最初の要素が1月を表すことがわかります。

+0

あなたはそれにスポットがあります。ありがとうございました...私は今、utl_fileを使ってxlsファイルにこれらの値を設定する必要があります。 –