SSMS
 sql >> Datenbank >  >> Database Tools >> SSMS

Die TSQL-Abfrage gibt Werte für jede Stunde der letzten 24 Stunden zurück

Ihr Problem scheint zu sein, dass die Zeitspanne in Stunden aufgeteilt werden muss. Sie müssen also mit allen Stunden des Tages beginnen. Dann berechnen Sie die Überlappung, summieren die Differenzen (unten in Millisekunden) und wandeln alles zurück in eine Zeit für die Ausgabe.

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

Damit dies funktioniert, müssen Sie außerdem „Beginn“ und „Ende“ in doppelte Anführungszeichen oder eckige Klammern setzen. Dies sind reservierte Wörter in T-SQL. Und Sie müssen das ". . ." mit zusätzlichen Linien für Stunden von 3 bis 22.