Reputation: 189
I know there are similar questions, but didn't find the answer for this specific case. Assume I have the following date ranges in the table (order by dates) :
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
The expected result is TRUE. This set contains consecutive date records (no gaps between) with overlaps
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
The expected result is TRUE. This set contains consecutive date records (no overlaps)
And for this case :
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
The result should be FALSE because there is a gap between 1st and 2nd rows (2017-01-16 is missing).
Thanks in advance.
Upvotes: 1
Views: 214
Reputation: 380
You could try just joining ranges by their order and comparing the last day of the first range and the first day of the second range
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
Upvotes: 0
Reputation: 13959
You can use lead to get this as below:
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
Upvotes: 0
Reputation: 5060
If the order is as in your sample data, you could try this, which uses LAG() function:
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;
Output 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;
Output 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;
Output 3:
+-----+
| CHK |
+-----+
| 0 |
+-----+
Upvotes: 0
Reputation: 1269493
If there is a gap, it is going to be one day before the end date or one day after the start date. You can get this list of dates and check for gaps. It is tricky, because you don't want the first and last of these dates . . . but, you can just set a threshhold of 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
);
Upvotes: 3