Résumer des plages de fractionnement dans une requête SQL
-
05-07-2019 - |
Question
J'ai une table contenant l'état de mon serveur
create table ServerStatus
(
ServerId int,
StartTime datetime,
Seconds int,
[State] char(8)
)
Je voudrais une requête qui donne une date de début et une date de fin qui récapitulera le temps que le serveur passe dans chaque état pendant cette période. Je voudrais également que la requête retourne la quantité de temps que les serveurs passent dans un état inconnu.
Donc, par exemple pour les données suivantes
1 2008-01-01 00:00:00.000 120 broken
1 2008-01-02 00:00:00.000 120 off
1 2008-01-03 00:00:00.000 240 burning
1 2008-01-04 00:00:00.000 60 off
1 2008-01-05 00:00:00.000 60 off
2 2008-01-01 00:00:00.000 60 broken
2 2008-01-02 00:00:00.000 30 off
2 2008-01-03 00:00:00.000 20 burning
2 2008-01-04 00:00:00.000 600 off
3 2007-01-04 00:00:00.000 600 off
4 2007-12-12 00:00:00.000 999999999 onfire
Fourni la plage.
select @start = dateadd(second, 60, '2008-01-01'),
@fin = dateadd(second, 60, '2008-01-04')
Je voudrais renvoyer les résultats:
1 broken 60
1 burning 240
1 off 180
1 unknown 258720
2 burning 20
2 off 90
2 unknown 259090
4 onfire 259200
Cette question est quelque peu liée à: Combinaison de plages de dates fractionnées dans un Requête SQL
La solution
C’est le meilleur que j’ai trouvé jusqu’à présent:
declare @start datetime
declare @fin datetime
select @start = dateadd(second, 60, '2008-01-01'), @fin = dateadd(second, 60, '2008-01-04')
select ServerId, State, Total = sum(
case when StartTime > @start and DateAdd(second, Seconds, StartTime) <= @fin
then Seconds
when StartTime < @start and DateAdd(second, Seconds, StartTime) <= @fin
then DateDiff(second, @start, DateAdd(second, Seconds, StartTime))
when StartTime < @start and DateAdd(second, Seconds, StartTime) >= @fin
then DateDiff(second, @start, @fin)
else
DateDiff(second,StartTime,@fin)
end)
into #t
from ServerStatus
where @start < dateadd(second, Seconds, StartTime)
and @fin > StartTime
group by ServerId, State
insert #t
select ServerId, 'unknown', DateDiff(second, @start, @fin) - sum(Total)
from #t
group by ServerId
having DateDiff(second, @start, @fin) > sum(Total)
select * from #t
order by ServerId, State
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow