如何从给定表中的To_date到to_date给出SQL中的日期范围?

时间:2016-09-08 10:01:29

标签: sql oracle date oracle10g

我在下面写了一个查询来生成一个日期序列,其中日期范围跨越12个月,第一个日期范围从from_date列开始,以to_date结束。 例如对于ITP_no 1 from_date是1-Apr-07而to_date是31-Mar-09然后op shoud be ITP_NO 2007年4月1日至2008年3月 2008年4月1日至2009年3月

Below is input table

ITP_NO  BILL_AMOUNT FROM_DATE   TO_DATE
1   58      1-Apr-07            31-Mar-08
1   58      1-Apr-07            31-Mar-08
1   58      1-Apr-07            31-Mar-08
1   58      1-Apr-07            31-Mar-08
1   58      1-Apr-07            31-Mar-08
1   116     1-Jan-09            31-Dec-11

查询:

    SELECT  ITP_NO ,level,
            BILL_AMOUNT ,From_Date,TO_DATE,
TO_CHAR(ADD_MONTHS(From_Date, (LEVEL - 1) * 12), 'MON-YYYY' ) || ' - '|| 
TO_CHAR(ADD_MONTHS(From_Date,  LEVEL * 12)-1, 'Mon-YYYY') as End_Date 
FROM (
            SELECT  ITP_NO,
                        BILL_AMOUNT,
                        From_Date,
                        TO_DATE 
            FROM test123

      )
CONNECT BY  ADD_MONTHS(From_Date, (LEVEL - 1) * 12)<TO_DATE

输出由:

ITP_NO LEVEL BILL_AMOUNT    FROM_DATE   TO_DATE     END_DATE



1   1   58      1-Apr-07    31-Mar-08   Apr-07-Mar-08
1   1   58      1-Apr-07    31-Mar-08   Apr-07-Mar-08
1   1   58      1-Apr-07    31-Mar-08   Apr-07-Mar-08
1   1   58      1-Apr-07    31-Mar-08   Apr-07-Mar-08
1   1   58      1-Apr-07    31-Mar-08   Apr-07-Mar-08
1   2   116     1-Jan-09    31-Dec-11   Jan-10-Dec-10
1   3   116     1-Jan-09    31-Dec-11   Jan-11-Dec-11
1   3   116     1-Jan-09    31-Dec-11   Jan-11-Dec-11
1   3   116     1-Jan-09    31-Dec-11   Jan-11-Dec-11
1   2   116     1-Jan-09    31-Dec-11   Jan-10-Dec-10
1   3   116     1-Jan-09    31-Dec-11   Jan-11-Dec-11
1   3   116     1-Jan-09    31-Dec-11   Jan-11-Dec-11
1   3   116     1-Jan-09    31-Dec-11   Jan-11-Dec-11
1   2   116     1-Jan-09    31-Dec-11   Jan-10-Dec-10
1   3   116     1-Jan-09    31-Dec-11   Jan-11-Dec-11
1   3   116     1-Jan-09    31-Dec-11   Jan-11-Dec-11
1   3   116     1-Jan-09    31-Dec-11   Jan-11-Dec-11
1   2   116     1-Jan-09    31-Dec-11   Jan-10-Dec-10
  

预期的O / P

  ITP_NO    BILL_AMOUNT FROM_DATE   TO_DATE END_DATE        
1   58  1-Apr-07    31-Mar-08   Apr-07- Mar-08  
1   58  1-Apr-07    31-Mar-08   Apr-07- Mar-08  
1   58  1-Apr-07    31-Mar-08   Apr-07- Mar-08  
1   58  1-Apr-07    31-Mar-08   Apr-07- Mar-08  
1   58  1-Apr-07    31-Mar-08   Apr-07- Mar-08  
1   116 1-Jan-09    31-Dec-11   Jan-09- Dec-10  
1   116 1-Jan-09    31-Dec-11   Jan-11- Dec-11  

1 个答案:

答案 0 :(得分:0)

我认为像这里的东西可能有用。在内部查询中添加row_number()并在connect by子句中使用它:

select t.*, 
       to_char(add_months(From_Date, (level - 1) * 12), 'yyyy-mm') || ' - '||  
       to_char(add_months(From_Date, (level * 12)) - 1, 'yyyy-mm') period
  from (
    select t.*, row_number() over (order by from_date, to_date) rn
      from test123 t) t
  connect by add_months(From_Date, (level - 1) * 12) <= to_date 
             and prior rn = rn and prior dbms_random.value is not null

您的输出和我的116有差异,但这是3年期间。

部分prior rn = rn and prior dbms_random.value is not null是分层查询中使用的技巧,用于阻止ORA-01436: CONNECT BY loop in user data

Oracle Row Generator Techniques

测试:

create table test123 (itp_no number(3), bill_amount number(6), from_date date, to_date date);
insert into test123 values (1,  58, date '2007-04-01', date '2008-03-31');
insert into test123 values (1,  58, date '2007-04-01', date '2008-03-31');
insert into test123 values (1,  58, date '2007-04-01', date '2008-03-31');
insert into test123 values (1,  58, date '2007-04-01', date '2008-03-31');
insert into test123 values (1,  58, date '2007-04-01', date '2008-03-31');
insert into test123 values (1, 116, date '2009-01-01', date '2011-12-31');


ITP_NO BILL_AMOUNT FROM_DATE   TO_DATE             RN PERIOD
------ ----------- ----------- ----------- ---------- -----------------
     1          58 2007-04-01  2008-03-31           1 2007-04 - 2008-03
     1          58 2007-04-01  2008-03-31           2 2007-04 - 2008-03
     1          58 2007-04-01  2008-03-31           3 2007-04 - 2008-03
     1          58 2007-04-01  2008-03-31           4 2007-04 - 2008-03
     1          58 2007-04-01  2008-03-31           5 2007-04 - 2008-03
     1         116 2009-01-01  2011-12-31           6 2009-01 - 2009-12
     1         116 2009-01-01  2011-12-31           6 2010-01 - 2010-12
     1         116 2009-01-01  2011-12-31           6 2011-01 - 2011-12