2

私はプロジェクト データのビューを与えられ、特定の月にいくつのプロジェクトが開かれていたかを要約するように求められました。

PROJECT_ID          OPEN_DATE         CLOSE_DATE         OWNER
         1          8/01/2012         09/01/2012          JEFF     
         2          8/08/2012         10/01/2012          JEFF     
         3          9/01/2012               Null          JEFF     
         4          9/12/2012               Null          JEFF     
         5          9/24/2012         11/01/2012          JEFF     
         6         10/01/2012         12/01/2012          JEFF     
         7         10/09/2012         01/01/2013          JEFF     

このようなOPENカウントが必要です。基本的なクエリを取得したら、プロジェクト オーナーごとにフィルタリング/グループ化する必要があります

AUG12   SEPT12   OCT12   NOV12   DEC12   JAN13   FEB13
2        4       5       4       3       2       1
^        ^       ^       ^       ^       ^       ^
|        |       |       |       |       |       |-> From Projects 3 & 4
|        |       |       |       |       |-> From Projects 3 & 4 
|        |       |       |       |-> From Projects 3,4 & 7
|        |       |       |-> From Projects 3,4,6 & 7
|        |       |-> From Projects 3,4,5,6 & 7
|        |-> From Projects 2,3,4, & 5                                    
|-> From Project 1 & 2

最新 これは、Gordon の提案による接続に基づいて私が持っているものです。クエリは約 4 ~ 5 秒遅い

SELECT SUM(case when (OPEN_DATE <= thedate and CLOSE_DATE > thedate) or (OPEN_DATE <= thedate and CLOSE_DATE Is Null) then 1 else 0 end) as Open 
1.     From (select * FROM Project 
2.     WHERE Project.Owner = :owner AND Project.action_for = :actionFor )  
3.     cross join (   select add_months(last_day(SYSDATE), level-7)

4.        as thedate from  dual connect by level <= 12   ) 
5.      group by to_char(thedate, 'YYYY-MM') order by 1

遅いだけでなく、実際のデータで正しく機能しているかどうかもわかりません。結果を手動で確認できる結果を得るには、クエリを分解する必要があります。SQLステートメントをどのようにデバッグしますか? 結果が得られたからといって、それらが正しいことをどのように知ることができますか?

4

2 に答える 2

1

これが1つの方法です。個別の列ではなく、個別の行に値を配置します。とにかく扱いやすいと思います:

select owner, to_char(thedate, 'YYYY-MM') as YYYYMM,
       SUM(case when open_date <= thedate and close_date > thedate then 1 else 0 end) as cnt
from project p cross join
     (select to_date('2012-08-31', 'yyyy-mm-dd') as thedate from dual union all
      select to_date('2012-09-30', 'yyyy-mm-dd') as thedate from dual union all
      select to_date('2012-10-31', 'yyyy-mm-dd') as thedate from dual union all
      select to_date('2012-11-30', 'yyyy-mm-dd') as thedate from dual union all
      select to_date('2012-12-31', 'yyyy-mm-dd') as thedate from dual union all
      select to_date('2013-01-31', 'yyyy-mm-dd') as thedate from dual union all
      select to_date('2013-02-28', 'yyyy-mm-dd') as thedate from dual
     ) as monthends
group by owner, to_char(thedate, 'YYYY-MM')
order by 1

任意の範囲の monthends テーブルを作成したい場合は、Oracle のconnect by構文について学ぶことができます。たくさんの月を取得する簡単な方法は次のとおりです。

select add_month('01Jan2000', rownum) - 1
from project
where rownum < 12 * 20

これにより、2000 年から 2019 年までの月末日が取得されます。

于 2013-02-27T22:50:47.877 に答える
1

これは、開始された月に終了されなかったプロジェクトの数を返します。これはあなたが求めていたもののように聞こえます

   SELECT to_char(open_date, 'MON-YYYY') as OpenMonths, count(*) as counts FROM 
  Project WHERE to_char(open_date,'MON-YYYY') <> to_char(close_date,'MON-YYYY') 
    GROUP BY to_char(open_date, 'MON-YYYY');

sqlfiddle へのリンクはこちらです。http://www.sqlfiddle.com/#!4/28bf5/1 DDL へのテキストが正しく検出されなかったため、null を他の例の日付に変更しました。

編集:

生成された月/年ディメンションを使用すると、このクエリは機能します

   SELECT monthid, count(*) as ProjectsOpen FROM
  (
   Select * FROm table1 CROSS JOIN mdim WHERE 
  (to_date(mdim.monthid,'MON-YYYY') >= table1.open_date ) AND (to_date(mdim.monthid,'MON-YYYY') <= table1.close_date)
  ) GROUP BY monthid;

月のディメンションは次のようなものです

     INSERT ALL 
 INTO mdim 
     VALUES ('JAN-2012')
INTO mdim 
     VALUES ('FEB-2012')
INTO mdim 
     VALUES ('MAR-2012')
INTO mdim 
     VALUES ('APR-2012')
INTO mdim 
     VALUES ('MAY-2012')
INTO mdim 
     VALUES ('JUN-2012')
INTO mdim 
     VALUES ('JUL-2012')
INTO mdim 
     VALUES ('AUG-2012')
INTO mdim 
     VALUES ('SEP-2012')
INTO mdim 
     VALUES ('OCT-2012')
INTO mdim 
     VALUES ('NOV-2012')
INTO mdim 
     VALUES ('DEC-2012')
INTO mdim 
     VALUES ('JAN-2013')
INTO mdim 
     VALUES ('FEB-2013')
INTO mdim 
     VALUES ('MAR-2013')
INTO mdim 
     VALUES ('APR-2013')
INTO mdim 
     VALUES ('MAY-2013')
INTO mdim 
     VALUES ('JUN-2013')
INTO mdim 
     VALUES ('JUL-2013')
INTO mdim 
     VALUES ('AUG-2013')
INTO mdim 
     VALUES ('SEP-2013')
INTO mdim 
     VALUES ('OCT-2013')
INTO mdim 
     VALUES ('NOV-2013')
INTO mdim 
     VALUES ('DEC-2013') 

SQLFiddle が csv インポートを台無しにしたので、任意の to_date キャストを行っています。ただし、この 2 番目のクエリでは、月のディメンションを設定すると、必要なデータが取得されます。

フィドル: http://www.sqlfiddle.com/#!4/ca8ac/34

于 2013-02-28T00:47:37.373 に答える