要获得预期结果,需要一些年月数据。我建议两种可能的方式来提供它:
- 创建一个包含所有可能的年月的表或视图;
- 创建一个仅返回所需年月的表函数。
其他选项假设隐式生成年月数据,我认为这不是一个明显的直接解决方案。
第二个选项(理论上)在更大的输入数据上可能会更快,但我不推荐它,因为你对性能只字未提,而且它比第一个更复杂。
最简单易用的解决方案是:
create table year (id int primary key);
insert into year values (2014);
insert into year values (2015);
insert into year values (2016);
create table month (id int primary key, name char(255));
insert into month values (1, 'Jan');
insert into month values (2, 'Feb');
insert into month values (3, 'Mar');
insert into month values (4, 'Apr');
insert into month values (5, 'May');
insert into month values (6, 'Jun');
insert into month values (7, 'Jul');
insert into month values (8, 'Aug');
insert into month values (9, 'Sep');
insert into month values (10, 'Oct');
insert into month values (11, 'Nov');
insert into month values (12, 'Dec');
create table data (id char(15) primary key , start_date date, end_date date);
insert into data
values ('XXA', to_date('1/23/14','MM/DD/RR'), to_date('3/12/14','MM/DD/RR'));
insert into data
values ('XXB', to_date('4/12/14','MM/DD/RR'), to_date('6/18/14','MM/DD/RR'));
create or replace view calendar as
select y.id*100 + m.id as id, y.id as year, m.name as month
from year y, month m;
select d.id, c.month, c.year
from calendar c, data d
where c.id between to_char(d.start_date, 'yyyymm')
and to_char(d.end_date, 'yyyymm');
输出是:
XXA|1月|2014年
---+---+----
XXA|2月|2014年
---+---+----
XXA|三月|2014
---+---+----
XXB|2014 年 4 月
---+---+----
XXB|五月|2014
---+---+----
XXB|六月|2014
提前填写年表很重要,否则它会一直工作到 2016 年。