Oracle11g Oracle:创建两个日期之间的月范围

Oracle11g Oracle:创建两个日期之间的月范围,oracle11g,Oracle11g,我有下表:如果需要,我还有一个日历表 ID Start_dt End_dt 1 1/9/2016 3/10/2016 预期产出: ID Start_dt End_dt Month ActiveCustomerPerMonth 1 1/9/16 3/10/2016 201601 1 1 1/9/16 3/10/2016 201602

我有下表:如果需要,我还有一个日历表

ID    Start_dt          End_dt
 1      1/9/2016         3/10/2016
预期产出:

ID    Start_dt      End_dt         Month   ActiveCustomerPerMonth
 1      1/9/16       3/10/2016    201601         1
 1      1/9/16       3/10/2016    201602         1
 1      1/9/16       3/10/2016    201603         0 (Not Active end of Month)
我需要这一点,因为我正在处理一个当前查询,该查询将利用一个案例陈述来统计客户当月是否活跃。如果该会员在当月最后一天处于活动状态,则该会员将被视为当月处于活动状态。但我需要能为那个客户数上几个月

  CASE 
     WHEN LAST_DAY(x.END_DT) = x.END_DT
       THEN '1'
     WHEN  TO_CHAR(X.END_DT,'MM/DD/YYYY') != '01/01/3000' 
       OR X.DISCHARGE_REASON IS NOT NULL 
        THEN '0'   
     WHEN X.FIRST_ASSGN_DT IS NULL
        THEN '0'      
   ELSE '1'
    END ActiveMemberForMonth
我是Oracle的新手,读过有关connect by的文章,但不了解该过程,也不确定这是否是正确的使用位置

类似这样的

with
     test_data ( id, start_dt, end_dt ) as (
       select 1, to_date('1/9/2016' , 'mm/dd/yyyy'), to_date('3/10/2016', 'mm/dd/yyyy') 
                                                                       from dual union all
       select 2, to_date('1/23/2016', 'mm/dd/yyyy'), to_date('5/31/2016', 'mm/dd/yyyy') 
                                                                       from dual
     )
--  end of test data; solution (SQL query) begins below this line
select id, start_dt, end_dt,
       to_char(add_months(trunc(start_dt, 'mm'), level - 1), 'yyyymm') as mth,
       case when end_dt < last_day(end_dt) 
             and level  = 1 + months_between(trunc(end_dt, 'mm'), trunc(start_dt, 'mm'))
            then 0 else 1 end as active_at_month_end
from   test_data
connect by level <= 1 +  months_between(trunc(end_dt, 'mm'), trunc(start_dt, 'mm'))
       and prior id = id
       and prior sys_guid() is not null
order by id, mth  --  optional
;

 ID START_DT   END_DT     MTH    ACTIVE_AT_MONTH_END
--- ---------- ---------- ------ -------------------
  1 2016-01-09 2016-03-10 201601                   1
  1 2016-01-09 2016-03-10 201602                   1
  1 2016-01-09 2016-03-10 201603                   0
  2 2016-01-23 2016-05-31 201601                   1
  2 2016-01-23 2016-05-31 201602                   1
  2 2016-01-23 2016-05-31 201603                   1
  2 2016-01-23 2016-05-31 201604                   1
  2 2016-01-23 2016-05-31 201605                   1

8 rows selected.

?? 请更详细地解释要求。似乎给了您一个开始日期和结束日期,并且您正在尝试生成几行,其中包含一个新的月份值。。。但规则是什么?在您的示例中,日期为2016年1月至5月,但月份为1月至3月。这里的业务逻辑是什么?@mathguy我已经更新了我的问题,以反映正确的日期。我试图根据我的案例陈述逻辑获得每月的活跃成员数,但需要确定该成员在该月是否活跃。如果该会员在月底活跃,则该会员在该月的想法或反馈被视为活跃?那么,如果月底是3月31日,客户在3月底活跃吗?我认为不是-这一定意味着他们在3月31日关闭了帐户,因此在午夜他们不再活跃,但您的业务要求可能不同。@mathguy客户将被视为活跃。我没有得到正确的结果。我现在已经删除了案例陈述,但下面是我的疑问。例如,Id 5776的起始日期为2013年1月15日,结束日期为2016年11月30日,我的返回结果不变。使用ActiveMemberData CLT_CLT_PGMID,startDate,EndDate作为选择不同的x.CLT_CLT_PGMID,TO_DATEx.start_dt,'DD/MM/YY'作为起始日期,TO_DATEx.enddt,“DD/MM/YY”作为ROSALIND.LTIH_PROGRAM_HIST X的结束日期在X.ID=D.ID上左连接联系人D,其中1=1,ID=5776选择不同的ID,开始日期,ActiveMemberData中的EndDate,其中1=1按级别连接您说我没有得到正确的结果是什么意思?你得到了什么是不正确的?从上面评论中快速阅读你的查询-你没有生成月份,我看不到你在哪里,所以我不确定它在做什么-即使没有标志的CASE表达式。那么:在您的表中是否可能多次出现相同的ID?那将是一个问题!对于先前的id=id部分,表中需要主键或唯一键。。。。或者,如果没有唯一键,可以使用Previor id=id和Previor start_date=start_date,前提是同一个客户端没有两个具有相同开始日期的不同行。