簡體   English   中英

如何在Sql Server中找到連續的日期范圍?

[英]How to find the continous range of dates in Sql Server?

我們如何從以下場景中找到連續的日期范圍?

    Id  modifiedDate  StartDate   EndDate
    1   2019-01-01    2019-01-01  2019-12-31
    1   2019-02-02    2019-02-01  2019-02-28
    1   2019-02-27    2019-01-15  2019-03-15
    1   2019-03-01    2019-03-01  2019-03-12
    2   2019-01-01    2019-01-01  2019-03-01
    2   2019-05-01    2019-05-01  2019-08-01

The Output i want to show is :

       Id  StartDate    EndDate
       1   2019-01-01   2019-01-15
       1   2019-01-15   2019-02-01
       1   2019-02-01   2019-02-28
       1   2019-02-28   2019-03-01
       1   2019-03-01   2019-03-12
       2   2019-01-01   2019-03-01
       2   2019-05-01   2019-08-01

到目前為止我嘗試過的是:

With X As(
Select a.StartDate,a.EndDate,b.StartDate,b.EndDate
From table a Full Join table b ON a.endDate>b.StartDate
Where a.StartDate<>b.StartDate and b.endDate<>a.Enddate
)
Select StartDate,Enddate,Min(StartDtae)
From X
Group By StartDate,EndDate

但我無法填補日期之間的空白。 我怎樣才能解決這個問題?

您可以使用CTE和Row_Number()的幫助嘗試以下腳本。 考慮到給定輸入數據的樣本輸出,我得到另外2行。 如果示例輸出正確,則可以忽略此解決方案。

CTE僅適用於MSSQL和Oracle。 但是你可以為任何其他數據庫轉換給定的邏輯。

WITH CTE
AS
(
    SELECT DISTINCT id,Date, ROW_NUMBER() OVER(PARTITION BY id ORDER BY Date) RN
    FROM
    (
        SELECT Id,StartDate Date FROM your_table
        UNION ALL
        SELECT Id,EndDate  FROM your_table
    ) A
)

SELECT A.Id, A.Date StartDate,B.Date EndDate 
FROM CTE A
INNER JOIN CTE B ON A.Id = B.Id AND A.RN = B.RN - 1

輸出是 -

Id  StartDate   EndDate
1   2019-01-01  2019-01-15
1   2019-01-15  2019-02-01
1   2019-02-01  2019-02-28
1   2019-02-28  2019-03-01
1   2019-03-01  2019-03-12
1   2019-03-12  2019-03-15 -- Not exist in your expected output
1   2019-03-15  2019-12-31 -- Not exist in your expected output

注意 :在下面添加額外的過濾將為您提供已發布的確切輸出。 但你自己決定哪一個最適合你的要求。

SELECT....
....
FROM CTE A
INNER JOIN CTE B ON A.Id = B.Id AND A.RN = B.RN - 1
WHERE B.DATE <= '2019-03-12' 

以下查詢應該為您提供所需的結果:

WITH dates AS (SELECT StartDate
                 FROM TABLE
                UNION
               SELECT EndDate + 1
                 FROM TABLE)
SELECT StartDate 
     , (SELECT MIN(StartDate) - 1
          FROM dates b
         WHERE StartDate - 1 > a.StartDate) EndDate
  FROM dates a 

只需使用帶union lead()

select t.id, t.dte as startdate,
       lead(t.dte) over (partition by t.id order by t.dte) as enddate
from (select distinct t.id, v.dte
      from t cross apply
           (values (startdate), (enddate)) v(dte)
     ) t;

除了簡潔之外,這可能具有最佳性能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM