oracle 合并日期区间,取天数

前端之家收集整理的这篇文章主要介绍了oracle 合并日期区间,取天数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在群里有人提了一个问题,不同日期区间包含的合并,取天数,如: 2015-01-01 2015-04-01 2015-03-01 2015-08-01

这里取的天数是2015-08-01-2015-01-01 下面是几个实现算法
### 1

with t as (

  select 'aa' as user_id,1 as orderid,to_date('2012-01-01','yyyy-mm-dd') as begin_date,to_date('2012-06-01','yyyy-mm-dd') as end_date from dual
  union all
  select 'aa' as user_id,2 as orderid,to_date('2012-03-01',to_date('2012-09-01',3 as orderid,to_date('2013-12-25','yyyy-mm-dd') as end_date from dual
  union all  
  select 'aa' as user_id,4 as orderid,to_date('2012-12-01',to_date('2013-12-01',5 as orderid,to_date('2014-12-01',to_date('2014-12-05','yyyy-mm-dd') as end_date from dual
  union all  
  select 'bb' as user_id,to_date('2012-08-01','yyyy-mm-dd') as end_date from dual
  union all
  select 'bb' as user_id,to_date('2013-06-01',to_date('2013-03-01','yyyy-mm-dd') as end_date from dual


  /*select 'aa' as user_id,to_date('2013-12-24',6 as orderid,to_date('2013-12-30','yyyy-mm-dd') as end_date from dual
*/),d as (
SELECT min_date + level -1 as is_date
FROM (select min(begin_date) min_date,max(end_date) max_date from t ) 
CONNECT BY level < max_date - min_date+1
)
select user_id,count(distinct is_date) from (
select * from t left join d on (is_date between begin_date and end_date)
) group by user_id

2

with ta as (
 select 'aa' as u_id,1 as oid,to_date('2015-01-01','yyyy-mm-dd') as bd,to_date('2015-06-01','yyyy-mm-dd') as ed from dual
  union all
  select 'aa' as user_id,to_date('2015-03-01',to_date('2015-09-01',to_date('2015-12-01',to_date('2016-12-25',to_date('2016-12-01',to_date('2016-12-24',to_date('2016-12-30',to_date('2015-08-01',to_date('2016-06-01',to_date('2016-03-01','yyyy-mm-dd') as end_date from dual
),t as (
select u_id,bd,max(oid) oid,max(ed) ed from ta group by u_id,bd
)
select uid2,sum(mbe - mbd + 1) n from (
select nnn,uid2,min(bd2) mbd,max(ed2) mbe from (
select connect_by_root (uid2 || '-' || oid2) nnn,t.* from (
select * from (
select row_number() over(partition by uid2,oid2,bd2,ed2 order by oid2,p  NULLS LAST ) rn,t.uid2,t.oid2,t.bd2,t.ed2,t.p,t.n from (
select case when t2.bd between t1.bd + 1 and t1.ed then t1.bd end p,case when t2.bd between t1.bd + 1 and t1.ed then t1.oid   end n,t1.u_id uid1,t1.oid oid1,t1.bd bd1,t1.ed ed1,t2.u_id uid2,t2.oid oid2,t2.bd bd2,t2.ed ed2 from t t1,t t2
where t1.u_id = t2.u_id and t1.oid <> t2.oid 
) t 
) where rn = 1
) t connect by  prior (uid2 || '-' || oid2) =  (uid2 || '-' || n) start with n is null 
) group by nnn,uid2
)group by uid2

3

with t as (
  select 'aa' as user_id,DIM_DATE as (
SELECT min_date + level -1 as DAY_DT
FROM (select min(begin_date) min_date,max(end_date) max_date from t ) 
CONNECT BY level <= max_date - min_date+1
)
--SELECT A.DAY_DT,T.USER_ID FROM  DIM_DATE A INNER  JOIN  T ON A.DAY_DT>=T.BEGIN_DATE AND A.DAY_DT<= T.END_DATE WHERE T.USER_ID = 'aa'
SELECT T.USER_ID,COUNT(distinct A.DAY_DT) FROM DIM_DATE A inner  
JOIN  T ON A.DAY_DT>=T.BEGIN_DATE AND A.DAY_DT<= T.END_DATE
GROUP BY T.USER_ID
;

4

with t as (
  select 'aa' as user_id,t2 as(select t.*,max(end_date)over(partition by user_id order by orderid) as t_max_date
 from t ),t3 as (select * from t2
minus 
select * from t2 where end_date<t_max_date
)

select user_id,sum(true_end_date-begin_date) from (
select t4.*,case when nvl(lead_begin_date,end_date)> end_date then end_date else nvl(lead_begin_date,end_date) end as true_end_date from (
select t3.*,lead(begin_date)over(partition by user_id order by orderid) as lead_begin_date from t3
) t4
) group by user_id
原文链接:https://www.f2er.com/oracle/211185.html

猜你在找的Oracle相关文章