select case when ( date'2012-02-25', date'2012-08-23' ) overlaps ( date'2012-08-13', date'2012-11-13' ) then 'It Overlaps' else 'nope' end as rslt from dual ;
So, being that it has very limited use, and that it is undocumented -- why even consider using it? Especially when there's a nice flexible supported construct that works just as well for numeric intervals as it does for date-time intervals.
Wasting no more time, then, here's the construct:
Given 2 intervals A and B (either numeric or date-time)in this form: A = ( A_bgn, A_end ) B = ( B_bgn, B_end ) * If they overlap, the following will return a TRUE value; if they don't overlap it will return FALSE. (This can be used in a WHERE clause or in a CASE statement.) >>> least(A_end, B_end) > greatest(A_bgn, B_bgn) * Similarly, this would test weather the intervals just touch: >>> least(A_end, B_end) = greatest(A_bgn, B_bgn) * The following will give you the actual length of overlap. For a date-time interval it will give you the number of days. For a numeric interval it returns the numeric distance. If the intervals don't overlap this will return a negative value indicating how far apart are the endpoints. >>> least(A_end, B_end) - greatest(A_bgn, B_bgn) * A simple modification will return 0 if there is no overlap and the length of the overlap if they actually do overlap. >>> greatest(least(A_end, B_end) - greatest(A_bgn, B_bgn), 0)
So as a quick example, here are two queries that use the above constructs.
One for numeric intervals and one for date-time intervals.
with w_data as ( select null as A_bgn , null as A_end , null as B_bgn , null as B_end from dual where 1=0 -------------------------------------------- union all select 11, 13, 16, 20 from dual union all select 12, 16, 14, 19 from dual union all select 10, 25, 15, 20 from dual union all select 12, 16, 16, 19 from dual -------------------------------------------- ) select greatest ( least(A_end, B_end) - greatest(A_bgn, B_bgn), 0) as intrvl_overlap , least(A_end, B_end) - greatest(A_bgn, B_bgn) as diff , case when least(A_end, B_end) > greatest(A_bgn, B_bgn) then 'overlapping' end as reslt , case when least(A_end, B_end) = greatest(A_bgn, B_bgn) then 'touches' end as reslt2 from w_data ;
And ...
with w_data as ( select null as A_bgn , null as A_end , null as B_bgn , null as B_end from dual where 1=0 -------------------------------------------------------------------------------------------------------- union all select to_date('0214~09:27','MMDD~HH24:MI'), to_date('0910~15:45','MMDD~HH24:MI') , to_date('0923~09:45','MMDD~HH24:MI'), to_date('1008~11:07','MMDD~HH24:MI') from dual union all select to_date('0214~09:27','MMDD~HH24:MI'), to_date('0825~15:45','MMDD~HH24:MI') , to_date('0705~09:45','MMDD~HH24:MI'), to_date('1008~11:07','MMDD~HH24:MI') from dual union all select to_date('0115~02:53','MMDD~HH24:MI'), to_date('1103~23:15','MMDD~HH24:MI') , to_date('0305~03:10','MMDD~HH24:MI'), to_date('0312~15:10','MMDD~HH24:MI') from dual union all select to_date('0411~08:53','MMDD~HH24:MI'), to_date('0416~13:30','MMDD~HH24:MI') , to_date('0416~13:30','MMDD~HH24:MI'), to_date('0425~07:42','MMDD~HH24:MI') from dual -------------------------------------------------------------------------------------------------------- ) select greatest ( least(A_end, B_end) - greatest(A_bgn, B_bgn), 0) as intrvl_overlap , least(A_end, B_end) - greatest(A_bgn, B_bgn) as diff , case when least(A_end, B_end) > greatest(A_bgn, B_bgn) then 'overlapping' end as reslt , case when least(A_end, B_end) = greatest(A_bgn, B_bgn) then 'touches' end as reslt2 from w_data ;