2017-09-15 124 views
1

如果我有開始和結束日期,然後是單獨的開始和結束時間,喜歡返回日期範圍內每個日期的時間範圍。將日期範圍和時間範圍組合到一組結果中,該結果包含日期範圍中包含的每一天的時間範圍SQL

這裏有一個小例子: 我有以下變量設置爲以下樣本值:

declare @StartDate date 
declare @EndDate date 
declare @StartTime time 
declare @EndTime time 
declare @interval int = 10 

set @StartDate = '2017-08-23' 
set @EndDate = '2017-08-25' 
set @StartTime = '07:00:00' 
set @EndTime = '07:30:00' 

什麼,我想回如下:

column1 
2017-08-23 07:00:00.000 
2017-08-23 07:10:00.000 
2017-08-23 07:20:00.000 
2017-08-23 07:30:00.000 
2017-08-24 07:00:00.000 
2017-08-24 07:10:00.000 
2017-08-24 07:20:00.000 
.... 

等。直到最終的日期時間值。

我想出了一個可行的解決方案(這可能會幫助一些人),但我覺得應該有一個更優雅的方式來實現相同的結果。

這裏是我的解決方案:

; 
WITH DateCTE 
     AS(
Select @StartDate as StartDate 
     UNION ALL 
     SELECT DATEADD(DAY,1,StartDate) 
    FROM DateCTE 
    WHERE DATEADD(DAY,1,StartDate) <= @EndDate 
     ) 

, TimeCTE 
     AS(
      Select @StartTime as StartTime 
       UNION ALL 
      SELECT DATEADD(MINUTE,@interval,StartTime) 
       FROM TimeCTE 
        WHERE DATEADD(MINUTE,@interval,StartTime) <= @EndTime 
     ) 

, DateTimeCTE 
      as (
       select StartDate, StartTime from DateCTE 
        cross join TimeCTE 
       ) 

SELECT CONVERT(DATETIME, CONVERT(CHAR(8), StartDate, 112) 
    + ' ' + CONVERT(CHAR(8), StartTime, 108)) as 'datetime' 
    FROM DateTimeCTE 
order by StartDate asc 
     ,StartTime asc 
; 

我擔心在查詢一切沿着三個熱膨脹係數可能使其體積太大。我是否有權爲此擔憂,還是我只是偏執狂? :)

在任何情況下,如果有人確實知道更清潔的解決方案,我會非常有興趣看到它。

再次感謝!

+1

這是工作代碼,應該發佈在CodeReview上,而不是SO上。 –

+0

標記您正在使用的dbms。該代碼是特定於產品的。 – jarlh

+2

這個問題屬於codereview.stackexchange.com – scsimon

回答

0

您可以遍歷您的範圍。例如,在SQL Server中,這將是

CREATE TABLE #Temp (result datetime) 
WHILE @StartDate <= @EndDate 
    WHILE @StartTime <= @EndTime 
     INSERT INTO # Temp VALUES (@StartDate + @StartTime) 
     SET @StartTime = DATEADD (minute, @StartTime, @interval) 
    END 
    SET @StartDate = DATEADD (day, @StartDate, 1) 
END 
0

鑄造這兩個項目爲日期時間,然後運行在一個CTE的WHERE時間部分(07:00 - 07:30)之間返回考慮一個遞歸CTE。但是,您可能需要擴大默認的最大遞歸:

  • 與定義的數字:option (maxrecursion 500)
  • 無限遞歸:option (maxrecursion 0)

Rextester演示(使用30由於間隔到它們的最大遞歸100)

declare @StartDate date; 
declare @EndDate date; 
declare @StartTime time; 
declare @EndTime time; 
declare @interval int = 10; 

set @StartDate = '2017-08-23'; 
set @EndDate = '2017-08-25'; 
set @StartTime = '07:00:00'; 
set @EndTime = '07:30:00'; 

WITH dates AS ( 
    SELECT CAST(CAST(@StartDate AS VARCHAR(10)) + ' ' + 
       CAST(@StartTime AS VARCHAR(8)) AS DATETIME) AS START_TIME 
    UNION ALL 
    SELECT DATEADD(MINUTE, @interval, START_TIME) 
    FROM dates 
    WHERE START_TIME < CAST(CAST(@EndDate AS VARCHAR(10)) + ' ' + 
          CAST(@EndTime AS VARCHAR(8)) AS DATETIME)  
) 

SELECT START_TIME FROM dates 
WHERE CONVERT(VARCHAR(8), START_TIME, 108) BETWEEN @StartTime AND @EndTime;