Michelle
Michelle

Reputation: 365

Find Date Gap Between Consecutive Start/End Date Columns

I have a table called periodDefinition with columns rowNum, periodSeq, startDate, endDate. I am trying to write a SQL query to find a gap between the endDate of one row and the startDate of the next row. Right now it's seeing a "gap" if the startDate of the next row isn't the exact same date as the endDate of the previous row.

Most advice seems to be to create a calendar temp table and double check against that, but due to work constriction policies, I cannot do that. Thanks for any advice you can give.

Sample Data:

rowNum: 1, periodSeq: 1, startDate: 09/01/2014, endDate: 09/30/2014

rowNum: 2, periodSeq: 2, startDate: 10/01/2014, endDate: 10/30/2014

rowNum: 3, periodSeq: 4, startDate: 11/01/2014, endDate: 11/30/2014

Test Query:

SELECT endDate, startDate
FROM
(
    SELECT DISTINCT startDate, ROW_NUMBER() OVER (ORDER BY startDate) RN
    FROM dbo.PeriodDefinition T1
    WHERE
        NOT EXISTS (
            SELECT *
            FROM dbo.PeriodDefinition T2
            WHERE T1.startDate > T2.startDate AND T1.startDate < T2.endDate
        )
    ) T1
JOIN (
    SELECT DISTINCT endDate, ROW_NUMBER() OVER (ORDER BY endDate) RN
    FROM dbo.PeriodDefinition T1
    WHERE
        NOT EXISTS (
            SELECT *
            FROM dbo.PeriodDefinition T2
            WHERE T1.endDate > T2.startDate AND T1.endDate < T2.endDate
        )
 ) T2
 ON T1.RN - 1 = T2.RN
WHERE
 endDate < startDate

Results:

endDate: 2014-09-30, startDate, 2014-01-01

endDate: 2014-09-30, startDate: 2014-11-01

endDate: 2014-10-30, startDate: 2014-12-01

Desired Results:

endDate: 2014-10-30, startDate: 2014-11-01

Upvotes: 1

Views: 3140

Answers (2)

JamieD77
JamieD77

Reputation: 13949

If you are interested in getting the missing dates you could do something like this using a recursive cte.

WITH cte AS (
    SELECT  MIN(startDate) startDate,
            MAX(startDate) endDate
    FROM    SampleData
    UNION ALL
    SELECT  DATEADD(day, 1, startDate),
            endDate
    FROM    cte 
    WHERE   DATEADD(day, 1, startDate) <= endDate
)

SELECT  cte.startDate 
FROM    cte
        LEFT JOIN SampleData s ON cte.startDate BETWEEN s.startDate AND s.endDate
WHERE   s.startDate IS NULL 
OPTION (MAXRECURSION 0);

SQL Fiddle

If you just want to use a query similar to yours, you can just use

SELECT
    endDate,
    startDate
FROM
    (SELECT startDate,
            ROW_NUMBER () OVER (ORDER BY startDate) RN 
     FROM   PeriodDefinition T1
    ) T1
    JOIN (SELECT endDate,
                 ROW_NUMBER () OVER (ORDER BY endDate) RN 
          FROM PeriodDefinition T1
    ) T2 ON T1.RN - 1 = T2.RN
WHERE
    endDate + 1 < startDate

SQL Fiddle

the problem with your query, that I saw, was that you were not adding 1 to the endDate in your where

Upvotes: 1

Tab Alleman
Tab Alleman

Reputation: 31785

Assuming that rowNum is sequential with no gaps.

Here's a simple way to get your desired result:

SELECT t1.EndDate, t2.StartDate
FROM PeriodDefinition t1
INNER JOIN PeriodDefinition t2
  ON t1.rowNum=t2.rowNum - 1
WHERE DATEDIFF(day, t1.EndDate, t2.StartDate)>1

Upvotes: 3

Related Questions