我需要您的帮助来解决此问题:
这是我的数据
id start_date end_date
5567 2008-04-17 2008-04-30
5567 2008-05-02 2008-07-31
5567 2008-08-01 2008-08-31
5567 2008-09-01 2009-12-31
由于在2008-04-30和2008-05-02之间存在间隔,因此要求显示间隔之后的最早开始日期。
id start_date end_date
5567 2008-05-02 2008-08-31
这是另一组数据:
id start_date end_date
5567 2008-04-17 2008-04-30
5567 2008-05-01 2008-07-31
5567 2008-08-01 2008-08-31
5567 2008-09-01 2009-12-31
在这种情况下,所有跨度都是连续的,因此最早的开始日期应在输出上。输出应为:
id start_date end_date
5567 2008-04-17 2008-04-30
这是我使用的代码:
select
id, min(start_date), contig
from (
select
id, start_date, end_date,
case
when lag(end_date) over (partition by id order by end_date) =
start_date-1 or row_number() over (partition by id order by
end_date)=1
then 'c' else 'l' end contig
from t2 )
group by id, contig;
当跨度之间没有间隔时,它会起作用,但是间隔出现时,它会给出两个记录。
例如,当跨度连续时,我的查询返回:
ID MIN(START_DATE CONTIG
5567 17-APR-08 c
但是,当数据不连续时,它将显示两个记录:
ID MIN(START_DATE CONTIG
5567 02-MAY-08 l
5567 17-APR-08 c
但是在这种情况下,我只想要第一个记录。
我知道有一个PL / SQL解决方案,但是我只能在SQL中实现吗?该数据库是Oracle 11gR2。
我认为这将满足您的要求:
select start_date
from (select t2.start_date
from t2 left join
t2 t2p
on t2.start_date = t2p.end_date + 1
where t2p.end_date is null
order by t2.start_date nulls last
) t
where rownum = 1;
您还可以使用以下方法执行此操作lag()
:
select coalesce(min(case when prev_end_date is not null then start_date end),
min(start_date))
from (select t2.*, lag(t2.end_date) over (order by t2.start_date) as prev_end_date
from t2
) t
where prev_end_date is null or prev_end_date <> start_date - 1;
您的“其他”情况有些棘手。您必须注意不要始终获得最短的开始日期。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句