Il s'agit d'un problème de "lacunes et d'îlots". J'ai truqué mes propres données de test (puisque vous n'en avez fourni aucune), mais je pense que cela fonctionne. L'intuition clé est que toutes les valeurs dans le même "îlot" (c'est-à-dire un intervalle de temps contigu) auront la même différence par rapport à une colonne row_number(). Si vous voulez en savoir un peu plus, faites une sélection brute à partir de IntervalsByDay
cte (par opposition à la sous-requête que j'ai maintenant); cela vous montrera les îles calculées (avec les points de départ et d'arrivée).
edit :je n'avais pas vu que tu avais un violon du premier coup. Ma réponse a été modifiée pour refléter vos données et le résultat souhaité
with i as (
select datediff(minute, '2013-01-01', StartTime) as s,
datediff(minute, '2013-01-01', EndTime) as e
from #track
), brokenDown as (
select distinct n.Number
from i
join dbadmin.dbo.Numbers as n
on n.Number >= i.s
and n.Number <= i.e
), brokenDownWithID as (
select Number, Number - row_number() over(order by Number) as IslandID,
cast(dateadd(minute, number, '2013-01-01') as date) as d
from brokenDown
), IntervalsByDay as (
select
dateadd(minute, min(number), '2013-01-01') as [IntervalStart],
dateadd(minute, max(number), '2013-01-01') as [IntervalEnd],
d,
max(Number) - min(Number) + 1 as [NumMinutes]
from brokenDownWithID
group by IslandID, d
)
select d, sum(NumMinutes) as NumMinutes
from IntervalsByDay
group by d
order by d