복붙노트

[SQL] SQL Server는 24 시간에 의해 지속 시간 행을 분할

SQL

SQL Server는 24 시간에 의해 지속 시간 행을 분할

나는 SQL 서버 2008 R2에서 일하고 있어요. 나는 FROMDATE, TODATE 사이에 24 개 시간 동안 범위에 의해 행을 분할하기 위해 노력하고있어. 시간 행이 아래로 주어진 경우 예를 들어, (FROMDATE 사이의 범위, TODATE 내가 4 개 행을 원하는, 그래서 4 일)

ID   FromDate                 Todate     
---- ------------------------ -------------------------
1    2014-04-01 08:00:00.000  2014-04-04 12:00:00.000

내가 같이보고 싶은 결과 :

ID   FromDate                 Todate                   DateDiff(HH)
---- ------------------------ -----------------------------------
1    2014-04-01 08:00:00.000  2014-04-01 23:59:59.000  15
1    2014-04-02 00:00:00.000  2014-04-02 23:59:59.000  23
1    2014-04-03 00:00:00.000  2014-04-03 23:59:59.000  23
1    2014-04-04 00:00:00.000  2014-04-04 12:00:00.000  12

해결법

  1. ==============================

    1.이 쿼리 검색 :

    이 쿼리 검색 :

    WITH TAB1 (ID,FROMDATE,TODATE1,TODATE) AS
    (SELECT ID,
    FROMDATE,
    DATEADD(SECOND, 24*60*60 - 1, CAST(CAST(FROMDATE AS DATE) AS DATETIME)) TODATE1,
    TODATE 
    FROM TABLE1
    UNION ALL
    SELECT 
    ID,
    DATEADD(HOUR, 24, CAST(CAST(TODATE1 AS DATE) AS DATETIME)) FROMDATE,
    DATEADD(SECOND, 2*24*60*60-1, CAST(CAST(TODATE1 AS DATE) AS DATETIME)) TODATE1,
    TODATE
    FROM TAB1 WHERE CAST(TODATE1 AS DATE) < CAST(TODATE AS DATE)
    ),
    TAB2 AS
    (SELECT ID,FROMDATE,
    CASE WHEN TODATE1 > TODATE THEN TODATE ELSE TODATE1 END AS TODATE
    FROM TAB1)
    SELECT TAB2.*,
    DATEPART(hh, TODATE) - DATEPART(hh, FROMDATE) [DateDiff(HH)] FROM TAB2;
    
  2. ==============================

    2.http://sqlfiddle.com/#!6/36452/2

    http://sqlfiddle.com/#!6/36452/2

    이것은 당신이 필요로해야한다. 쿼리의 첫 번째 부분은 재귀 CTE이다. 이것은 날짜 데이터를 만드는 데 사용할 수 있습니다.

    WITH CTEDays AS
    (
        SELECT CONVERT(date, '20140301') datevalue
     UNION ALL
        SELECT DATEADD(day, 1, C.datevalue)
        FROM CTEDays C
        WHERE DATEADD(day, 1, C.datevalue) <= '20140501'
    )
    SELECT 
        R.FromDate [FromOriginal]
        , R.ToDate [ToOriginal]
        , CDays.datevalue [RawDate]
        , WantedFrom = 
            CASE WHEN CONVERT(date, R.FromDate) = CDays.datevalue THEN R.FromDate
                 ELSE CDays.datevalue
            END
        , WantedTo = 
            CASE WHEN CONVERT(date, R.ToDate) = CDays.datevalue THEN R.ToDate
                 ELSE DATEADD(minute, 24*60-1, CONVERT(datetime, CDays.datevalue))
            END
    FROM 
        tblRange R
        OUTER APPLY
        (
            SELECT C.datevalue
            FROM CTEDays C
            WHERE C.datevalue BETWEEN CONVERT(date, R.FromDate) AND CONVERT(date, R.ToDate)
        ) CDays
    

    그러나, 나는 CTE가 너무 느리거나 불편하면, 이것에 대한 일정 테이블을 설정하는 것이 좋습니다 것입니다.

    (내가 여기 제안으로)

  3. ==============================

    3.이것은 당신이 필요로하는 무엇을 얻어야한다. 당신이 범위에 /에서 큰 날짜 범위를 사용하는 경우 그냥 세트 MAXRECURSION해야합니다.

    이것은 당신이 필요로하는 무엇을 얻어야한다. 당신이 범위에 /에서 큰 날짜 범위를 사용하는 경우 그냥 세트 MAXRECURSION해야합니다.

    http://sqlfiddle.com/#!6/68b32/233

    declare @tblTemp TABLE (id int identity, fromDate datetime, toDate datetime)
    
    insert @tblTemp(fromDate, toDate)
    select '2014-01-01 12:00:00', '2014-01-02 12:00:00'
    union select '2014-04-01 12:00:00', '2014-04-02 12:00:00'
    
    
    ;with cte(i, f, t, e) as (
        select id as i, fromDate as f, DATEADD(SS, -1, DATEADD(HH, 1, fromDate)) as t, toDate as e
        from @tblTemp
        union all
        select cte.i as i, DATEADD(SS, 1, cte.t), DATEADD(HH, 1, cte.t) as t, cte.e as e
        from cte
        where DATEADD(HH,1,cte.t) <= cte.e
    )
    select i, f, t 
    from cte
    order by i,f
    
  4. from https://stackoverflow.com/questions/22435556/sql-server-split-a-time-duration-row-by-24-hour-period by cc-by-sa and MIT license