-1

収益貢献期間に基づいて、1か月にアクティブな顧客の数を取得する必要があります。

元のデータ:

ACCOUNT_ID  REVENUE_START_DATE       REVENUE_END_DATE
1234         1/14/2010 0:00          4/13/2010 23:59
4567         2/9/2010 0:00           3/8/2010 23:59
1234         5/9/2010 0:00           6/8/2010 23:59

期待される結果

Month   Count
Dec-09  0
Jan-10  1
Feb-10  2
Mar-10  2
Apr-10  1
May-10  1
Jun-10  1
Jul-10  0
Aug-10  0
Sep-10  
Oct-10  

以下は私が(グーグルの助けを借りて)取り組んだオラクルコードですが、日付が重複しているために正しい結果が得られません。私は専門家にこれを手伝ってくれるように頼みます。(前もって感謝します)

現在の結果:

YEAR_   MONTH_  ACT
2010    January     2
2010    February    3
2010    March       3
2010    April       3

オラクルコード:

with tab as
(
     select distinct ACCOUNT_ID,  billing_start_date as revenue_start_date, billing_end_date as revenue_end_date
     from accounts
                ),                    
     year_tab as 
                (
                    select 
                             add_months(min_date, level -1) m
                    from 
                            (
                            select min(trunc(revenue_start_date,'YYYY')) min_date, add_months(max(trunc(revenue_end_date,'YYYY')), 12) max_date
                            from tab
                            )
                    connect by level <= months_between(max_date, min_date)
              )     
select to_char(m,'YYYY') year_,
         to_char(m,'Month') month_,
         nvl(act, 0) act
from   year_tab,
            (            
            select m date_,count(*)  act
            from tab, year_tab
            where m between trunc(revenue_start_date,'MM') and trunc(revenue_end_date,'MM')
            group by m
            ) month_tab
where m = date_(+)
order by m;
4

1 に答える 1

0

なぜあなたが問題があると思うのかを理解するのに少し時間がかかりました。提供した元の3行のデータを使用して、クエリを実行すると、正確に「期待される結果」が得られます。CSVファイルの54行のデータを使用すると、結果は48行(4年間をカバー)になり、2010年1月から2013年1月までの合計はゼロ以外になります。返される最初の数行は次のとおりです。

YEAR_ MONTH_                                      ACT
----- ------------------------------------ ----------
2010  January                                       2 
2010  February                                      3 
2010  March                                         3 
2010  April                                         3
2010  May                                           2 

しかし、それは正しいように見えます:

select * from accounts
where not (billing_start_date > date '2010-02-01'
        or billing_end_date < date '2010-01-01');

ACCOUNT_ID BILLING_START_DATE BILLING_END_DATE 
---------- ------------------ ------------------
      1234 09/01/2010 00:00   08/02/2010 23:59   
      4567 14/01/2010 00:00   13/04/2010 23:59   

 2 rows selected 

select * from accounts
where not (billing_start_date > date '2010-03-01'
        or billing_end_date < date '2010-02-01');

ACCOUNT_ID BILLING_START_DATE BILLING_END_DATE 
---------- ------------------ ------------------
      1234 09/01/2010 00:00   08/02/2010 23:59   
      4567 14/01/2010 00:00   13/04/2010 23:59   
      1234 09/02/2010 00:00   08/03/2010 23:59   

 3 rows selected 

select * from accounts
where not (billing_start_date > date '2010-04-01'
        or billing_end_date < date '2010-03-01');

ACCOUNT_ID BILLING_START_DATE BILLING_END_DATE 
---------- ------------------ ------------------
      4567 14/01/2010 00:00   13/04/2010 23:59   
      1234 09/02/2010 00:00   08/03/2010 23:59   
      1234 09/03/2010 00:00   08/04/2010 23:59   

 3 rows selected 

しかし、あなたが望んでいたことは、「顧客の数をアクティブにする」という質問ではあまり強調されていませんでした。「顧客」が一意のアカウントIDを意味すると仮定すると、カウントを変更する必要があります。

    select m date_,count(distinct account_id)  act
    from tab, year_tab
    ...

...これにより、最初の数行が次のようになります。

YEAR_ MONTH_                                      ACT
----- ------------------------------------ ----------
2010  January                                       2 
2010  February                                      2 
2010  March                                         2 
2010  April                                         2 
2010  May                                           1 

あなたが間違っていたのdistinctは、tabサブクエリにを適用しようとしたことでした。ただし、distinctは別個の行を返します。日付が異なるため、実際に返される行の数は減りませんでした。

これはまだ期待される結果と完全には一致しませんが、データと一致しているように見え(必要なものについての私の仮定が正しい場合)、3行のサンプルに対して期待される結果を提供します。


クエリを作成する別の方法。これは、ANSI結合構文を使用して、従うのが少し簡単だと思います。

with t as (
    select add_months(min_date, level - 1) month_start,
        add_months(min_date, level) next_month_start
    from (
        select trunc(min(billing_start_date),'YYYY') min_date,
            add_months(trunc(max(billing_start_date),'YYYY'), 12) max_date
        from accounts
    )
    connect by level <= months_between(max_date, min_date)
)
select to_char(t.month_start,'YYYY') year_,
    to_char(t.month_start,'Month') month_,
    count(distinct a.account_id) act
from t
left join accounts a on not (billing_start_date > t.next_month_start
    or billing_end_date < t.month_start)
group by t.month_start
order by t.month_start;
于 2013-02-08T22:04:01.907 に答える