我有这些日期范围代表订阅的开始和结束日期。日期范围没有重叠。
Start Date End Date
1/5/2015 - 1/14/2015
1/15/2015 - 1/20/2015
1/24/2015 - 1/28/2015
1/29/2015 - 2/3/2015
我想确定任何订阅结束和新订阅结束之间超过1天的延迟。例如对于上面的数据,我想要输出:1/24/2015 - 1/28/2015
。
如何使用SQL查询执行此操作?
编辑:此外,订阅日期范围内可能存在多个空白,但我想要在最新的日期范围之后的日期范围。
答案 0 :(得分:0)
您可以使用left join
或not exists
:
select t.*
from t
where not exists (select 1
from t t2
where t2.enddate = dateadd(day, -1, t.startdate)
);
请注意,这也会为您提供序列中的第一条记录。 。 。严格来说,这符合条件。以下是该问题的一种解决方案:
select t.*
from t cross join
(select min(startdate) as minsd from t) as x
where not exists (select 1
from t t2
where t2.enddate = dateadd(day, -1, t.startdate)
) and
t.startdate <> minsd;
你也可以使用窗口函数来解决这个问题:
select t.*
from (select t.*,
lag(enddate) over (order by startdate) as prev_enddate,
min(startdate) over () as min_startdate
from t
) t
where minstartdate <> startdate and
enddate <> dateadd(day, -1, startdate);
另请注意,此逻辑假定时间段不重叠。如果他们这样做,需要更清晰的问题陈述来理解你真正想要的东西。
答案 1 :(得分:0)
您可以使用窗口函数LAG()
来实现此目的,该函数将从有序集中的上一行获取值,以便稍后在WHERE
子句中进行比较。然后,在WHERE
中,您只需应用&#34;间隙定义&#34;并丢弃第一行。
<强> SQL FIDDLE - Test it! 强>
示例数据:
create table dates(start_date date, end_date date);
insert into dates values
('2015-01-05','2015-01-14'),
('2015-01-15','2015-01-20'),
('2015-01-24','2015-01-28'), -- gap
('2015-01-29','2015-02-03'),
('2015-02-04','2015-02-07'),
('2015-02-09','2015-02-11'); -- gap
查询
SELECT
start_date,
end_date
FROM (
SELECT
start_date,
end_date,
LAG(end_date, 1) OVER (ORDER BY start_date) AS prev_end_date
FROM dates
) foo
WHERE
start_date IS DISTINCT FROM ( prev_end_date + 1 ) -- compare current row start_date with previous row end_date + 1 day
AND prev_end_date IS NOT NULL -- discard first row, which has null value in LAG() calculation
我假设您的数据没有重叠,并且每对都有唯一的值。如果情况并非如此,您需要澄清这一点。