2017-09-15 32 views
1

開始日と終了日、そして別の開始日と終了日を持つ場合、日付範囲内の各日の時間範囲を返すようにします。日付範囲と時間範囲を、日付範囲に含まれる各日の時間範囲を含む一連の結果に結合するSQL

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 
.... 

等...ゴマ:

ここで小さな例だ: 私は、次の変数は、以下のサンプルの値に設定されている:

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' 

私は返すしたいことは以下のとおりです。最終日時の値。

私はこの解決策(いくつかの人々に役立つかもしれません)を考え出しましたが、同じ結果を達成するためのよりエレガントな方法が必要であると感じています。私は、クエリ内の他のすべてと一緒に3つのCTEは、それがあまりにもかさばる作ることを心配しています

; 
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

これは動作するコードであり、SOではなくCodeReviewに掲載する必要があります。 –

+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

が日時などの2つの項目をキャストしてから時間部分(07:00 - 07:30)の間に戻るCTEにWHEREを実行することによって、1再帰CTEを考えるだろう。無限再帰をoption (maxrecursion 500)

  • :定義された数で

    • :ただし、デフォルトの最大再帰を拡大する必要があるかもしれませんoption (maxrecursion 0)

    が原因30の間隔を使用していますRextesterデモを(参照してください。 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;