当我尝试以递归方式计算每个plan_period的周期时,我的查询卡在永恒循环中。以下是我的尝试:
WITH p (period_id, start_period, end_period )
AS (SELECT
PERIOD_VERSIO,
To_date(FROM_PERIOD, 'YYYYMM'),
To_date(TO_PERIOD, 'YYYYMM')
FROM SOR_MAP_PLAN_PERIOD),
date_ranges
AS (SELECT
distinct
period_id,
To_char(start_period, 'YYYYMM') as START_PERIOD,
To_char(Add_months (start_period, LEVEL - 1), 'YYYYMM') as END_PERIOD
FROM p
CONNECT BY LEVEL <= Months_between( end_period, start_period ) + 1)
SELECT d.period_id as "KEY",
-- d.start_period,
d.end_period as PERIOD,
e.end_period as PLAN_PERIOD
FROM date_ranges d
--order by 3,2
full outer join (SELECT period_id,end_period
FROM date_ranges
) e on e.period_id=d.period_id
ORDER BY 3, 2, 1
;
Parameter table:
PERIOD_VERSIO FROM_PERIOD TO_PERIOD
201612_BU 201701 201712
201705_STR 201801 202012
201706_SRT1 201801 202012
201709_LE 201710 201809
通缉结果:
PERIOD_VERSIO PERIOD PLAN_PERIOD
201612_BU 201701 201701
201612_BU 201702 201701
201612_BU 201703 201701
201612_BU 201704 201701
201612_BU 201705 201701
201612_BU 201706 201701
201612_BU 201707 201701
201612_BU 201708 201701
201612_BU 201709 201701
201612_BU 201710 201701
201612_BU 201711 201701
201612_BU 201712 201701
201612_BU 201701 201702
201612_BU 201702 201702
201612_BU 201703 201702
201612_BU 201704 201702
…..
…..
201706_SRT1 201801 201801
201706_SRT1 201802 201801
201706_SRT1 201803 201801
201706_SRT1 201804 201801
201706_SRT1 201805 201801
201706_SRT1 201806 201801
201706_SRT1 201808 201801
201706_SRT1 201808 201801
201706_SRT1 201809 201801
201706_SRT1 201810 201801
201706_SRT1 201811 201801
201706_SRT1 201812 201801
……
201706_SRT1 201801 202012
201706_SRT1 201802 202012
201706_SRT1 201803 202012
201706_SRT1 201804 202012
201706_SRT1 201805 202012
201706_SRT1 201806 202012
201706_SRT1 201808 202012
201706_SRT1 201808 202012
201706_SRT1 201809 202012
201706_SRT1 201810 202012
201706_SRT1 201811 202012
201706_SRT1 201812 202012
答案 0 :(得分:1)
这可以在纯SQL中完成。
首先,我们有一个递归的WITH子句,它生成每个period_versio'. Then there's join two instances of that subquery which produces all the permutations of generated months for the
period_versio&#39;的开始和结束时段所涵盖的所有月份。
with mths (period_id, period_st, period_end, lvl) as (
select period_versio,
cast(to_date(from_period, 'yyyymm') as date),
cast(to_date(to_period, 'yyyymm') as date),
1
from sor_map_plan_period
union all
select period_id,
cast(add_months(period_st, 1) as date),
cast(period_end as date),
lvl+1
from mths
where lvl < months_between(period_end, period_st)
)
select t1.period_id as period_versio
,to_char( t1.period_st, 'yyyymm') as period
,to_char( t2.period_end, 'yyyymm') as plan_period
from
( select period_id,
period_st
from mths) t1
join
(select period_id,
period_end
from mths) t2
on t1.period_id = t2.period_id
order by 1, 2, 3
/
Oracle 11gR2中引入了递归WITH子句。在传递日期时,它有一个令人讨厌的错误,投掷ORA-01790
。因此需要围绕显然已经过日期的事物看起来很奇怪的CAST
表达式。如果您正在使用12c,则可能不需要它们。
答案 1 :(得分:0)
您的查询可能就像这样简单:
select period_versio
,ym as period
,from_period plan_period
from parameter_t a
join periods_t b on(
b.ym >= a.from_period
and b.ym <= a.to_period
);
...如果你有一个句号表......如果你打算与他们一起工作,你应该拥有它。以下是如何创建2000 - 2030年期间的表格。
create table periods_t(
ym number not null
,year number not null
,month number not null
,primary key(ym)
);
insert
into periods_t(ym, year, month)
select year || lpad(month, 2, '0') as ym
,year
,month
from (select 1999 + level as year from dual connect by level <= 30) y
,(select level as month from dual connect by level <= 12) m;
我从示例参数
中假设了以下表结构create table parameter_t(
period_versio varchar2(20) not null
,from_period number(6) not null
,to_period number(6) not null
);
insert into parameter_t values('201612_BU', 201701, 201712);
insert into parameter_t values('201705_STR', 201801, 202012);
insert into parameter_t values('201706_SRT1', 201801, 202012);
insert into parameter_t values('201709_LE', 201710, 201809);