码迷,mamicode.com
首页 > 数据库 > 详细

Oracle数据整理

时间:2015-06-04 00:41:48      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:

1.表中有四个字段:人员编号,开始时间,结束时间,类型,数据ID,需要实现如下需求

a.当类型为-1时,丢弃该记录

b.当类型为-1时,且前一行结束时间为null,当前行的开始时间-1作为前一行的结束时间

c.如果后面的时间比前面的时间早,则覆盖前面的时间,不能覆盖的时间要保留

d.时间段重叠的要合并为一行

with x1 as
(select userid,startdate,coalesce(min(case when type=-1 then add_months(startdate,-1) else startdate end) over(partition by userid order by vid rows between 1 following and unbouded following),startdate+1) as minsdate, enddate as orgenddate,
case when enddate is null and (lead(type) over(partition by userid order by vid))=-1 then add_months((lead(startdate) over(partition by userid order by vid)),-1) else enddate end as enddate,type,vid,
max(vid) over(partition by userid) as max_id from test,
 x2 as
(select userid,startdate,minsdate,enddate,type,vid,max_id,
  case when (lag(enddate) over(partition by userid order by vid))<add_months(startdate,-1) then 1
  when (lag(type) over(partition by userid order by vid))=1 then null else 1 end as so from x1),
x3 as 
(select userid,vid,max_id,type,sum(so) over(partition by userid order by vid) as so,
           startdate,minsdate,
           case when minsdate<enddate and minsdate>=startdate then minsdate else enddate end as enddate
           from x2 where type=1 and startdate<=minsdate),
x4 as
(select userid,max_id,max(vid) as max_id2,sum(type) as type,
           min(startdate) keep(dense_rank first order by vid) as startdate,
           max(enddate) keep(dense_rank last order by vid) as enddate
  from x3)
select userid,to_char(startdate,yyyymm)||--||coalesce(to_char(enddate,yyyymm),NULL) as rangeSpace
from x4
where (max_id=max_id2 or startdate<=enddate) and type>-1;

Oracle数据整理

标签:

原文地址:http://www.cnblogs.com/zhulongchao/p/4550538.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!