如何使用SQL间隔表报告间隙?

时间:2015-05-13 15:03:23

标签: sql sql-server sql-server-2014

我有下表没有重叠的间隔,我想报告所有可能的差距?

我拥有的表格:

Id         StartDateTime        EndDateTime

3004204 | 2014-01-01 12:47 | 2014-01-01 12:59
3004204 | 2014-01-01 13:00 | 2014-01-01 14:29
3004204 | 2014-01-01 14:30 | 2014-01-01 14:41
3004204 | 2014-01-02 18:01 | 2014-01-02 18:14
3004204 | 2014-01-02 18:15 | 2014-01-02 18:29
3004204 | 2014-01-02 18:30 | 2014-01-02 18:44
3004204 | 2014-01-02 18:45 | 2014-01-02 18:59
3004204 | 2014-01-02 19:00 | 2014-01-02 19:29

我想要的是每个Id每天的差距报告。所以在这种情况下它将是:

Id          StartDateTime       EndDateTime

3004204 | 2014-01-01 12:59 | 2014-01-01 13:00
3004204 | 2014-01-01 14:29 | 2014-01-01 14:30
3004204 | 2014-01-02 18:14 | 2014-01-02 18:15
...

注意:间隙可以是1秒到23:59小时之间的任意长度(目前仅显示每秒)。我认为需要使用滞后来完成,但这似乎效率很低。

是否有任何建议在SQL Server 2014中是否可以以比使用延迟和潜在客户更有效的方式实现?

由于

2 个答案:

答案 0 :(得分:2)

使用LEAD()查找每天每个ID的差距。它高效而简单。

SELECT *
FROM
(
    SELECT  ID,
            [GapStart]  = EndDateTime,
            [GapEnd]    = LEAD(StartDateTime) OVER (PARTITION BY ID, CAST(StartDateTime AS DATE) ORDER BY StartDateTime)
    FROM @yourTable
) A
WHERE GapEnd IS NOT NULL --Filters out last row of each day

答案 1 :(得分:0)

它不漂亮,但它应该有用。

select * from  (
    select a.Id,a.EndDate,b.StartDate
      ,row_number() over (partition by a.EndDate order by b.StartDate) as r
    from temp.test a inner join
      temp.test b on a.EndDate <= b.StartDate
    where year(a.EndDate) = year(b.StartDate)
      and month(a.EndDate) = month(b.StartDate)
      and day(a.EndDate) = day(b.StartDate)) as t
     where r = 1 and EndDate != StartDate

*忘记添加最终过滤器以消除EndDate = StartDate