在sql中的日期范围中找出差距之后的日期

时间:2016-02-10 23:14:07

标签: sql date

我有这些日期范围代表订阅的开始和结束日期。日期范围没有重叠。

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查询执行此操作?

编辑:此外,订阅日期范围内可能存在多个空白,但我想要在最新的日期范围之后的日期范围。

2 个答案:

答案 0 :(得分:0)

您可以使用left joinnot 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

我假设您的数据没有重叠,并且每对都有唯一的值。如果情况并非如此,您需要澄清这一点。