SSMS
 sql >> Base de données >  >> Database Tools >> SSMS

La requête TSQL renvoie des valeurs pour chaque heure des dernières 24 heures

Votre problème semble être que le laps de temps doit être divisé en heures. Donc, vous devez commencer par toutes les heures de la journée. Ensuite, vous calculez le chevauchement, additionnez les différences (ci-dessous en millisecondes) et convertissez tout en temps pour la sortie.

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

De plus, pour que cela fonctionne, vous devez envelopper "begin" et "end" entre guillemets doubles ou crochets. Ce sont des mots réservés dans T-SQL. Et vous devez remplacer le ". . ." avec des lignes supplémentaires pour les heures de 3 à 22.