TSQL Query returns values for each hour for the past 24 hours

前端 未结 2 1298
隐瞒了意图╮
隐瞒了意图╮ 2021-01-22 20:48

I have a query that I don\'t really know how to begin with. I\'m hoping someone can help me out with it. I will start by explaining the table

I have a device table with

相关标签:
2条回答
  • 2021-01-22 21:02

    Something like this might get you started.

    select  SUM(datediff(second, Begin_dt, End_dt)) as seconds_online
            ,DATEPART(hour, Begin_dt) as [hour]
    from table
    where device_status in (1,4,5)
    group by DATEPART(hour, Begin_dt)
    

    To format the result you may want to follow this question:

    SQL - Seconds to Day, Hour, Minute, Second

    0 讨论(0)
  • 2021-01-22 21:17

    Your problem seems to be that the time span needs to be broken up in hours. So, you need to start with all hours in the day. Then you calculate the overlap, sum up the differences (below in milliseconds) and convert everything back to a time for the output.

    with const as (
            select dateadd(hour, 1, cast(cast(getdate() -1 as date) as datetime)) as midnight            
        ),
        allhours as (
            select 0 as hour, midnight as timestart, dateadd(hour, 1, midnight) as timeend from const union all
            select 1 as hour, dateadd(hour, 1, midnight), dateadd(hour, 2, midnight) from const union all
            select 2 as hour, dateadd(hour, 2, midnight), dateadd(hour, 3, midnight)  from const union all
            . . .
            select 23 as hour, dateadd(hour, 23, midnight), dateadd(hour, 24, midnight) from const
        )
    select ah.hour,
           sum(datediff(ms, (case when ah.timestart >= dt.begin then timestart else dt.begin end),
                            (case when ah.timeend <= dt.end then ah.timeend else dt.end end)
                       ) 
               ) as totalms,
           cast(dateadd(ms, sum(datediff(ms, (case when ah.timestart >= dt.begin then timestart else dt.begin end),
                                         (case when ah.timeend <= dt.end then ah.timeend else dt.end end)
                                        )
                               ),
                         0) as time
               ) as totalTime
    from allhours ah left outer join
         DeviceTable dt
         on ah.timestart< coalesce(dt.end, getdate()) and
            ah.timeend >= dt.begin
    group by ah.hour
    order by ah.hour
    

    Also, to make this work, you need to wrap "begin" and "end" in double quotes or square brackets. These are reserved words in T-SQL. And you need to replace the ". . ." with additional lines for hours from 3 to 22.

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