我在下面写了一个查询来生成一个日期序列,其中日期范围跨越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
答案 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