如何在SQL Server中确定具有重叠的连续日期记录

时间:2017-05-22 12:13:04

标签: sql sql-server datetime

我知道有类似的问题,但没有找到这个具体案例的答案。假设我在表格中有以下日期范围(按日期排序):

 StartDate   -   EndDate      DoW
----------------------------------
 2017-01-10  -   2017-01-15    1
 2017-01-16  -   2017-01-19    2
 2017-01-17  -   2017-01-19    3
 2017-01-18  -   2017-01-21    4
 2017-01-22  -   2017-01-28    5

预期结果为 TRUE 。该集包含重叠的连续日期记录(无间隙)

 StartDate   -   EndDate      DoW
----------------------------------
 2017-01-10  -   2017-01-15    1
 2017-01-16  -   2017-01-19    2
 2017-01-20  -   2017-01-23    3
 2017-01-24  -   2017-01-26    4
 2017-01-27  -   2017-01-28    5

预期结果为 TRUE 。该集包含连续的日期记录(无重叠)

对于这种情况:

StartDate   -   EndDate      DoW
---------------------------------
 2017-01-10  -   2017-01-15    1
 2017-01-17  -   2017-01-19    2
 2017-01-17  -   2017-01-19    3
 2017-01-18  -   2017-01-21    4
 2017-01-22  -   2017-01-28    5

结果应为 FALSE ,因为第1行和第2行之间存在差距(缺少2017-01-16)。

提前致谢。

4 个答案:

答案 0 :(得分:3)

如果存在差距,则会在结束日期前一天或开始日期后一天。您可以获取此日期列表并检查差距。这很棘手,因为你不想要这些日期的第一个和最后一个。 。 。但是,你可以设置一个2的门槛:

with d as (
      select dateadd(day, -1, startdate) as dte
      from t
      union all  -- do not remove duplicates!
      select dateadd(day, + 1, enddate) as dte
      from t
     )
select (case when count(*) > 2 then 'false' else 'true' end)
from d
where not exists (select 1
                  from t
                  where d.dte >= t.startdate and
                        d.dte <= t.enddate
                 );

答案 1 :(得分:0)

如果订单与样本数据一样,您可以尝试使用LAG()函数:

CREATE TABLE TT1 (STARTDATE DATE, ENDDATE DATE, DOW INT);

1)

INSERT INTO TT1 VALUES ('2017-01-10','2017-01-15',    1);
 INSERT INTO TT1 VALUES ('2017-01-16','2017-01-19',    2);
 INSERT INTO TT1 VALUES ('2017-01-17','2017-01-19',    3);
 INSERT INTO TT1 VALUES ('2017-01-18','2017-01-21',    4);
 INSERT INTO TT1 VALUES ('2017-01-22','2017-01-28',    5);


SELECT MIN(CHCK)  AS CHK
FROM (
        SELECT CASE WHEN DATEDIFF(dd, LAG(ENDDATE) OVER (ORDER BY DOW), STARTDATE) >1 THEN 0 ELSE 1 END AS CHCK
        FROM TT1
       ) A;

 DELETE FROM TT1;

输出1:

+-----+
| CHK |
+-----+
| 1   |
+-----+

2)

 INSERT INTO TT1 VALUES ('2017-01-10','2017-01-15',    1);
 INSERT INTO TT1 VALUES ('2017-01-16','2017-01-19',    2);
 INSERT INTO TT1 VALUES ('2017-01-20','2017-01-23',    3);
 INSERT INTO TT1 VALUES ('2017-01-24','2017-01-26',    4);
 INSERT INTO TT1 VALUES ('2017-01-27','2017-01-28',    5);

SELECT MIN(CHCK)  AS CHK
FROM (
        SELECT CASE WHEN DATEDIFF(dd, LAG(ENDDATE) OVER (ORDER BY DOW), STARTDATE) >1 THEN 0 ELSE 1 END AS CHCK
        FROM TT1
       ) A;

 DELETE FROM TT1;

输出2:

+-----+
| CHK |
+-----+
| 1   |
+-----+

3)

 INSERT INTO TT1 VALUES ('2017-01-10','2017-01-15',    1);
 INSERT INTO TT1 VALUES ('2017-01-17','2017-01-19',    2);
 INSERT INTO TT1 VALUES ('2017-01-17','2017-01-19',    3);
 INSERT INTO TT1 VALUES ('2017-01-18','2017-01-21',    4);
 INSERT INTO TT1 VALUES ('2017-01-22','2017-01-28',    5);

SELECT MIN(CHCK)  AS CHK
FROM (
        SELECT CASE WHEN DATEDIFF(dd, LAG(ENDDATE) OVER (ORDER BY DOW), STARTDATE) >1 THEN 0 ELSE 1 END AS CHCK
        FROM TT1
       ) A;

输出3:

+-----+
| CHK |
+-----+
| 0   |
+-----+

答案 2 :(得分:0)

您可以尝试按顺序加入范围,并比较第一个范围的最后一天和第二个范围的第一天

SELECT  iif(count(*)>0, 0, 1) as result 
FROM    t prev 
left outer join t next on (prev.Dow+1) = next.Dow 
where
DATEADD(d, 1, prev.EndDate) < next.StartDate

答案 3 :(得分:0)

您可以使用线索获取如下内容:

select case when count(*) = sum(nextdt) then 'true' else 'false' end as Result
from (
    select *, NextDt = case when dateadd(dd, 1, enddate) = lead(startdate, 1, dateadd(dd, 1, enddate)) over(order by startdate) then 1 else 0 end from #yourconsequentdate
) a