SQL Server , split a time duration row by 24 hour period

前端 未结 3 419
野的像风
野的像风 2020-12-03 14:37

I\'m working on sql server 2008 r2. I\'m trying to split a row by 24 hours period ranges between FromDate, Todate. For example, if a time r

相关标签:
3条回答
  • 2020-12-03 15:21

    This should get you what you need. Just remember to set maxrecursion if you are using large date ranges in from/to range.

    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
    
    0 讨论(0)
  • 2020-12-03 15:25

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

    This should be what you need. The first part of the query is a recursive CTE. This can be used to create the dates-data.

    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
    

    However, I would suggest to set up a calendar table for this, if the CTE is too slow or inconvenient.

    (as I have suggested here)

    0 讨论(0)
  • 2020-12-03 15:33

    Try this query:

    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;
    

    SQL Fiddle

    0 讨论(0)
提交回复
热议问题