sql >> Base de Datos >  >> Database Tools >> SSMS

Consulta TSQL devuelve valores para cada hora durante las últimas 24 horas

Su problema parece ser que el lapso de tiempo debe dividirse en horas. Por lo tanto, debe comenzar con todas las horas del día. Luego, calcula la superposición, suma las diferencias (a continuación en milisegundos) y vuelve a convertir todo a una hora para la salida.

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

Además, para que esto funcione, debe incluir "begin" y "end" entre comillas dobles o corchetes. Estas son palabras reservadas en T-SQL. Y necesita reemplazar el ". . ." con líneas adicionales para el horario de 3 a 22.