Select 中断发生前日期范围内的最早日期

Select Earliest Date Within a Range of Dates Before a Break Occurs

我一直在努力寻找一种解决方案,以从一系列日期范围中获取最近的开始日期。我在 Whosebug 和其他网站上找到了类似的主题,但 none 适合我的特定场景。

以下是我数据库中的两个数据示例:

示例 1

Start Date | End Date
-----------|-----------
8/26/2006  | 5/31/2016
6/1/2016   | 12/31/2017
1/1/2018   | NULL

对于这个例子,我希望查询的结果是:8/26/2006。这是因为开始日期和结束日期是连续的,一直到原始开始日期。

示例 2

Start Date | End Date
-----------|-----------
7/6/2014   | 11/30/2014
1/1/2019   | NULL

对于这个例子,我希望查询的结果是:1/1/2019。这是因为 11/30/2014 和 1/1/2019 之间有休息时间。

我不需要所有日期的列表,甚至不需要返回的结束日期。我只需要日期范围中断之前的最早开始日期。

我猜我需要的是循环遍历记录的递归 CTE,例如:

WITH CTE AS
  (
    SELECT
      T1.StartDate
     ,T1.EndDate
    FROM
      ExampleTable AS T1
    LEFT JOIN
      ExampleTable AS T2
        ON
        T1.EmployeeID = T2.EmployeeID
          AND T1.StartDate - 1 = T2.EndDate
    WHERE
      T1.EmployeeID = @EmployeeID
    UNION ALL
    SELECT
      C.EmployeeID
     ,C.StartDate
     ,T2.EndDate
    FROM
      CTE AS C
    JOIN
      ExampleTable AS T2
        ON
        C.EmployeeID = T2.EmployeeID
          AND T2.StartDate - 1 = C.EndDate
  )
SELECT
  StartDate
 ,NULLIF(MAX(ISNULL(EndDate, '32121231')), '32121231') AS EndDate
FROM
  CTE
GROUP BY
  StartDate;

但运气不好。它总是 returns 我在示例 1 或 2 中列出的所有日期范围。有人可以帮忙吗?

这似乎是获得结果的最简单方法:

SELECT TOP 1 StartDate
FROM YourTable
ORDER BY CASE WHEN LAG(EndDate) OVER (ORDER BY StartDate) = DATEADD(DAY,-1,StartDate) THEN 1 ELSE 0 END,
         StartDate DESC;

因此,对于您的数据:

WITH VTE AS(
    SELECT CONVERT(date, StartDate,101) AS StartDate,
           CONVERT(date, EndDate,101) AS EndDate
    FROM (VALUES('7/6/2014','11/30/2014'),
                ('1/1/2019',NULL)) V(StartDate, EndDate))
SELECT TOP 1 StartDate
FROM VTE
ORDER BY CASE WHEN LAG(EndDate) OVER (ORDER BY StartDate) = DATEADD(DAY,-1,StartDate) THEN 1 ELSE 0 END,
         StartDate DESC;

WITH VTE AS(
    SELECT CONVERT(date, StartDate,101) AS StartDate,
           CONVERT(date, EndDate,101) AS EndDate
    FROM (VALUES('8/26/2006','5/31/2016'),
                ('6/1/2016 ','12/31/2017'),
                ('1/1/2018 ',NULL)) V(StartDate, EndDate))
SELECT TOP 1 StartDate
FROM VTE
ORDER BY CASE WHEN LAG(EndDate) OVER (ORDER BY StartDate) = DATEADD(DAY,-1,StartDate) THEN 1 ELSE 0 END,
         StartDate DESC;