问题描述
很抱歉,标题...最好用一个例子来描述问题...
Sorry for the title ... it's best to describe the problem with an example ...
我有一个事件列表和每个事件的两个日期,我需要在各自的月份内中断"或分发"这些日期.
I have a list of events and two dates for each event and I need to "break" or "distribute" those dates within their respective months.
示例1:
事件:事件A
开始日期:2017年12月15日-MM/DD/YYYY
Start Date: 12/15/2017 - MM/DD/YYYY
结束日期:2018年1月17日-MM/DD/YYYY
End Date: 01/17/2018 - MM/DD/YYYY
如果我在表上搜索此事件,则会得到包含该数据的结果行.
If I do a search on my table for this event, I get a result row with that data.
但是我需要两个结果,如下所示:
But I need two results, as shown below:
结果1:事件A> 15至31
结果2:事件A> 01至17
示例2:
事件:事件B
开始日期:2018年7月7日-MM/DD/YYYY
Start Date: 02/07/2018 - MM/DD/YYYY
结束日期:2018年4月22日-MM/DD/YYYY
End Date: 04/22/2018 - MM/DD/YYYY
结果1:事件B> 07至28
结果2:事件B> 01至31
结果3:事件B> 01至22
最有效的方法是什么?
推荐答案
在Oracle 12c中,可以使用cross apply
子句:
On Oracle 12c cross apply
clause can be used:
create table e_vents(
name varchar2(10),
startdate date,
enddate date
);
insert all
into e_vents values( 'A', date '2017-12-15', date '2018-01-17' )
into e_vents values( 'B', date '2017-12-15', date '2017-12-22' )
into e_vents values( 'C', date '2017-12-15', date '2018-05-22' )
select null from dual;
commit;
select e.name,
case when e.startdate > x.s_date then e.startdate else x.s_date end as start_date,
case when e.enddate < x.e_date then e.enddate else x.e_date end as end_date
from e_vents e
cross apply (
select
trunc( e.startdate, 'mm') + (level-1) * interval '1' month as s_date,
trunc( e.startdate + (level) * interval '1' month, 'mm') -1 as e_date
from dual
connect by level <= months_between( trunc( e.enddate, 'mm'),trunc( e.startdate, 'mm')) + 1
) x
NAME START_DATE END_DATE
---------- ---------- ----------
A 2017-12-15 2017-12-31
A 2018-01-01 2018-01-17
B 2017-12-15 2017-12-22
C 2017-12-15 2017-12-31
C 2018-01-01 2018-01-31
C 2018-02-01 2018-02-28
C 2018-03-01 2018-03-31
C 2018-04-01 2018-04-30
C 2018-05-01 2018-05-22
9 rows selected.
这篇关于如何将两个日期之间的间隔按月拆分为详细信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!